Jump to content
Crispy

Cosmic Ark Star Field Revisited

Recommended Posts

I've had one remaining issue lurking in my FPGA TIA core for some time now, and I finally got around to working on it. Of course I'm talking about the famous Cosmic Ark star field. I've read through many posts on the subject, and unless I missed some critical information somewhere, it appears that the behavior and the underlying cause of the effect are not fully understood. So, I decided to pull out my scope, and dig into it myself.

There are two parts to the star field effect. The first is well understood. You can trick the extra clock logic into generating extra clocks indefinitely after an HMOVE by changing the value in the HMMx (or HMPx, or HMBL) register so that the comparison that resets the extra clocks enable line never happens. Once the logic is in this state, extra clocks are continuously generated once every four system clocks until HMOVE is written again.
The second part of the effect is where the mystery lies, and I was completely baffled by it when I first saw on the scope what the TIA was doing. Instead of always producing one clock wide pixels, the effect occasionally produces two clock wide and zero clock wide pixels. In the posts that I've read on the subject, the pattern is described as two single wide pixels followed by a double wide pixel and then no pixel, each shifted 15 pixels left from the position on the previous line. However, the actual pattern is more complex than this, as we can see in the following table.
LINE	PIXEL	WIDTH	DELTA	BLANKING
----------------------------------------
5	54	4	--	*
6	10	4	-44	*
6	214	0	+204
7	197	1	-17
8	180	1	-17
9	162	2	-18
10	146	0	-16
11	129	1	-17
12	112	1	-17
13	94	2	-18
14	78	0	-16
15	38	4	-40	*
15	221	1	+183
16	204	1	-17
17	186	2	-18
18	170	0	-16
19	153	1	-17
20	136	1	-17
21	118	2	-18
22	102	0	-16
23	85	1	-17
24	66	3	-19	*
25	0	2	-66	*
25	210	2	+210
26	194	0	-16
27	177	1	-17
28	160	1	-17
29	142	2	-18
30	126	0	-16
First off, the NTSC TIA produces 68 pixel clocks of horizontal blanking. This translates to 17 extra clocks per line, and so the shift is actually 17 pixels. But more interestingly, the progression of the pattern changes when a pixel straddles blanking and active video. An example of this behavior can be seen on line 24 at pixel 66. If we were to follow the pattern of 1-1-2-0 from line 19 pixel 153, then the pixel on line 25 at clock 210 should have zero width, but it is actually double wide.
So what actually causes the pixels to sometimes be normal width and at other times be double or zero width? If we look at the schematic we see that the clock for the missile logic is formed by ORing the motion clock with an inverted copy of the extra clocks. Under normal circumstances these two clock lines are not active at the same time, but that's not the case here. When the inverted extra clocks line goes high, the motion clock line goes low. Do these two events happen at the exact same time? If not then there will be a glitch on the missile clock line every time an extra clock is generated, and if this is the case then does the missile logic see this glitch as a valid clock edge? I found the answer to these questions by looking at the TIA READY and XTAL pins with my scope, and using the measured time difference to arrive at a rough estimate of the average propogation delay through a single gate. Based on this information, I calculated that the motion clock line goes low 21.5 ns before the inverted extra clocks line goes high, and the resulting glitch has a pulse width long enough to create a valid clock edge for the missile logic.
post-41074-0-47001100-1485724616_thumb.png
Now that my FPGA design was correct, I ran a simulation of it to see exactly what the TIA is doing when extra clocks are present during active video. Under normal conditions the missile clock and the pixel clock transition from low to high at the same time. When this happens a pixel at the input of the serial graphics latch will be latched at its output, and the missile logic updates causing the pixel to be removed from the latch input. The result is one pixel into the latch and one pixel out.
post-41074-0-76661000-1485724642_thumb.png
Things get more interesting when the missile logic is about to produce a pixel, and an extra clock occurs. In this case the glitch on the missile clock line causes the missile logic to update early, and put a pixel at the input of the latch. I marked this event in red. Then at the time when the pixel clock does switch, there is already a pixel at the latch input. The missile logic isn't updated at this time because the missile clock line has already transitioned from low to high when the extra clock occurred. After this when the next pixel clock edge comes along, things are back to normal. The pixel on the latch input is latched to its output, and the missile logic updates and removes the pixel from the latch input. The result of all this is a double wide pixel that occurs one clock early.
post-41074-0-50014400-1485724669_thumb.png
A similar chain of events occur when there is a pixel at the latch input at the time when an extra clock occurs. In this case the missile logic updates early, and removes the pixel from the latch input. Then when the pixel clock transitions from low to high, a logic low is latched at its output. The resulting effect is that no pixel is produced from the latch.
post-41074-0-57309900-1485724679_thumb.png
So there it is. The star field pattern is the result of two different clock timings beating against each other. I've included my simulation data in a zip file for anyone interested. You will need GTKWave to view it. http://gtkwave.sourceforge.net
  • Like 15
  • Thanks 1

Share this post


Link to post
Share on other sites

Thanks a lot for your analysis.

 

I found that wider objects behave slightly different. And the size changes not anymore when the object is at last 4 pixel wide. Also missile and players behave a bit different. And some consoles (Chinese Jr.) behave quite different.

 

Maybe you can cover those cases too?

Share this post


Link to post
Share on other sites

And some consoles (Chinese Jr.) behave quite different.

 

It would be very useful if Stella emulated that different TIA behaviour. Unfortunately many people don't have access to these specific configurations and therefore the software does not display as expected on these real consoles.

Share this post


Link to post
Share on other sites

I ran a simulation of the player 0 sprite with extra clocks always enabled, and these are the points I took away from my analysis.

  • The sprite position follows the same progression from line to line as the missile position.
  • The sprite is always eight pixels wide during active video.
  • There is always at least one bit that is not displayed followed by the next bit displayed as a double wide pixel.
  • Two double wide pixels are separated by four pixel clocks.
  • The bit to the right of a double wide bit will be displayed as a double wide pixel on the next line. For example, if bits 6 and 2 are double wide this line, then bits 5 and 1 will be double wide next line.
Here we see that bits 5 and 1 are not displayed, and bits 4 and 0 are displayed as double wide pixels.
post-41074-0-55572000-1486166830_thumb.png
On the next line bits 4 and 0 are not displayed, and bit 3 is double wide.
post-41074-0-41635100-1486167788_thumb.png
I'll get back to looking at the missile at its 2x, 4x, and 8x sizes in a few days. Until then, here's my simulation data for the player 0 sprite.
Edited by Crispy

Share this post


Link to post
Share on other sites

Trying to understand this.

 

What do you mean with "The sprite is always eight pixels wide during active video."? If only one pixel of a (single sized) sprite, then you still see 8 pixel?

Share this post


Link to post
Share on other sites

Trying to understand this.

 

What do you mean with "The sprite is always eight pixels wide during active video."? If only one pixel of a (single sized) sprite, then you still see 8 pixel?

 

Yes, I should have been more descriptive. What I should have said is that the active sprite time is always eight pixel clocks, because there are always one or more sprite bits that are skipped, and one or more sprite bits that are displayed as double wide pixels. So in all cases when the lower three bits of the NUSIZx register are set to anything other than 5 or 7, then the sprite is always 8 clocks wide. I haven't looked at the cases for double size or quad size players yet.

Share this post


Link to post
Share on other sites

Ok, but within the eight pixels of the sprite, you can e.g. activate only one pixel. Then this pixel (almost) behaves like a missile.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...