Jump to content

# A simple display timing diagram

## Recommended Posts

Here's something I should have done ages ago. It's a simple text diagram showing the timing of every pixel on the screen. This makes timing calculations for an async playfield much easier.

2222222222222222222222333333333333333333333333333333444444444444444444444444444444555555555555555555555555555555666666666666666666666666666666777777777777777777 2333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555666777888999000111222333444555 ................................................................................................................................................................ 6036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036036

4444555566667777777766665555444433332222111100000000111122223333444455556666777777776666555544443333222211110000000011112222333344445555666677777777666655554444

000000001111111122222222333333334444444455555555

The first 4 rows are a vertically written number. For example, the first number is 22.6, and the last number is 75.6. These numbers are the fractional scanline cycle count at the time each pixel is displayed. There are 160 numbers, corresponding to the 160 pixels of the visible screen.

The next row shows all the blocks of the playfield using a mirrored configuration. (PF0 PF1 PF2 PF2 PF1 PF0)

The last row is a 6 sprite display, which you can move around as needed.

From this diagram, it is clear that the STA PF2 must start at cycle 46 and end at cycle 48 to perfectly synchronize with a reflected playfield. This has been useful for determining exact timing for the other playfield stores as well.

#### Share this post

##### Share on other sites

Here's something I should have done ages ago.

Andrew Davie produced a nice diagram with this information on it some time ago. I can't find the original thread, so I've attached the diagram below.

Chris

#### Share this post

##### Share on other sites

Here's something I should have done ages ago.

Andrew Davie produced a nice diagram with this information on it some time ago. I can't find the original thread, so I've attached the diagram below.

Chris

Also, you need to be aware that there's a small delay when writing to the playfield registers, so you must complete the write a few cycles earlier than you'd otherwise expect-- I can't recall the exact number, I think it's something like 1.67 or 2.67. (Yes, it's an oddball number, perhaps because the playfield counter is updated once every four color clocks, instead of once every three color clocks like the ratio of CPU cycles to color clocks.) I made some tables and had posted them to the Stella mailing list. I'll dig them up tonight and post them here. But also beware that some "compatible" machines seem to require an extra little bit, probably because they use "back-engineered ripoffs" of the TIA instead of a "real" TIA.

Michael

#### Share this post

##### Share on other sites

Also, you need to be aware that there's a small delay when writing to the playfield registers, so you must complete the write a few cycles earlier than you'd otherwise expect-- I can't recall the exact number, I think it's something like 1.67 or 2.67. (Yes, it's an oddball number, perhaps because the playfield counter is updated once every four color clocks, instead of once every three color clocks like the ratio of CPU cycles to color clocks.) I made some tables and had posted them to the Stella mailing list. I'll dig them up tonight and post them here. But also beware that some "compatible" machines seem to require an extra little bit, probably because they use "back-engineered ripoffs" of the TIA instead of a "real" TIA.

Michael

How does the Stella emulator handle the playfield delay? I often use mirrored mode for asynchronous playfield display, which is particularly picky for the center PF2 to PF2 transition. Only a PF2 store that completes at the end of cycle 48 will work. One cycle earlier or later will result in mangled graphics for either the first or second PF2 display.

How common are the ripoff machines?

I'm having trouble saving that timing image with the new forum interface. When the attachment loads up in my browser, right clicking doesn't provide the usual "Save image as" option. It only allows a save page option. I'm using Firefox 3.5.2.

TIA (Thanks in Advance)

#### Share this post

##### Share on other sites

I'm having trouble saving that timing image with the new forum interface. When the attachment loads up in my browser, right clicking doesn't provide the usual "Save image as" option. It only allows a save page option. I'm using Firefox 3.5.2.

If you go to the board index and click the little paperclip next to the title, you can open the attachment directly. There must be an easier way to do this from within the thread, but I can't find it.

Chris

#### Share this post

##### Share on other sites

Also, you need to be aware that there's a small delay when writing to the playfield registers, so you must complete the write a few cycles earlier than you'd otherwise expect-- I can't recall the exact number, I think it's something like 1.67 or 2.67. (Yes, it's an oddball number, perhaps because the playfield counter is updated once every four color clocks, instead of once every three color clocks like the ratio of CPU cycles to color clocks.) I made some tables and had posted them to the Stella mailing list. I'll dig them up tonight and post them here. But also beware that some "compatible" machines seem to require an extra little bit, probably because they use "back-engineered ripoffs" of the TIA instead of a "real" TIA.

Michael

How does the Stella emulator handle the playfield delay? I often use mirrored mode for asynchronous playfield display, which is particularly picky for the center PF2 to PF2 transition. Only a PF2 store that completes at the end of cycle 48 will work. One cycle earlier or later will result in mangled graphics for either the first or second PF2 display.

How common are the ripoff machines?

I'm having trouble saving that timing image with the new forum interface. When the attachment loads up in my browser, right clicking doesn't provide the usual "Save image as" option. It only allows a save page option. I'm using Firefox 3.5.2.

TIA (Thanks in Advance)

I was wrong about the delay-- it's only 2/3 of a machine cycle for standard consoles, and 1 full cycle for the non-standard consoles. I'm not sure if the "non-standard" consoles are only certain compatible "clones" that use a back-engineered TIA-wannabee, or if certain later versions of the 7800 also have the slightly longer delay. Anyway, the cycle 48 you mentioned is always true for the right copy of PF2 in a reflected (or "mirrored") playfield.

I found the two Stella posts where I had posted my tables:

http://atari2600.org/pipermail/stella/2008-July/020544.html

http://atari2600.org/pipermail/stella/2008-July/020551.html

I'm including the tables in this post, with a revised explanation.

The following tables show the latest cycles at which you can write to the playfield registers, for each individual playfield pixel (as well as the beginning of HBLANK). The first two tables show how the numbers are determined, and the last table presents the numbers in a compact format.

You'll want to use a fixed-spacing font for the tables. Also, the first two tables use four special characters-- the division symbol, as well as superscripts 0, 1, and 2-- so you need a font with those characters in it (which should be just about any fixed-spacing font). "Courier New" is fine, but I think "Lucida Console" looks best. The superscripted numbers represent thirds, for remainders, so a superscript of 0 is "no-thirds" (or no remainder), a superscript of 1 is "one-third" (or a remainder of 1), and a superscript of 2 is "two-thirds" (or a remainder of 2). The first table shows the calculations for a repeated playfield, and the second table shows the calculations for a reflected playfield.

Following is an explanation of what the first set of tables are showing. The first row shows the color clock where each playfield pixel begins. We divide by 3 to get the machine cycle, but there could be a remainder of 1 or 2, so the third row shows the result of the division along with the remainder (0, 1, or 2). Then we subtract 2/3 of a cycle to allow for the delay, so the fifth row shows the result of the subtraction along with the fractional part. Then we drop any fractional part to get the final result in the seventh row.

Why do the tables for each individual playfield pixel? Well, 99% of the time you'd want the new value of a playfield register to be displayed in its entirety. But if you're ever in a situation where it would be okay to update a playfield a little earlier or later than usual-- because you aren't using some of the leftmost or rightmost pixels of that playfield register-- then you might want to get down to the pixel level.

Also, the values for the last pixel of each playfield register determine the *earliest* you can update that playfield register for its next copy. For example, if you're using a repeated playfield, the left copy of PF0 must be updated no later than cycle 22, otherwise the display will be "corrupted," combining a little bit of the old value of PF0 with the new value of PF0. Similarly, the earliest you could update PF0 again without displaying part of the new value is cycle 27. For the right copy of PF0, the latest cycle to display the new value is cycle 48, and the earliest you could update PF0 again is cycle 53. So if you put those together, you see that (when using a repeated playfield) the value for the left copy of PF0 must be written between cycle 53 (of the previous scan line) and cycle 22 (of the current scan line), whereas the value for the right copy of PF0 must be written between cycle 27 and cycle 48.

You can also see what would happen if you update a playfield register at an oddball or "incorrect" time. For example, if you write a new value to PF1 at cycle 33, the first five pixels of the left copy of PF1 will show the old value, and the last three pixels of the left copy of PF1 will show the new value.

Just to be sure, these cycle numbers represent the next cycle after the write instruction has finished. For example, "STA PF1" takes 3 cycles, so if the instruction begins on cycle 28, it will span cycles 28, 29, and 30, hence the next cycle after the write instruction has finished will be cycle 31.

Repeated Playfield:

```=================
| HBLANK | 000  |
|        | ÷ 3  |
|        |  00º |
|        |  - ² |
|        |  75¹ |
|        |------|
|        |  75  |
======================================
| L. PF0 | 068  | 072  | 076  | 080  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  22² |  24º |  25¹ |  26² |
|        |  - ² |  - ² |  - ² |  - ² |
|        |  22º |  23¹ |  24² |  26º |
|        |------|------|------|------|
|        |  22  |  23  |  24  |  26  |
==================================================================
| L. PF1 | 084  | 088  | 092  | 096  | 100  | 104  | 108  | 112  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  28º |  29¹ |  30² |  32º |  33¹ |  34² |  36º |  37¹ |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  27¹ |  28² |  30º |  31¹ |  32² |  34º |  35¹ |  36² |
|        |------|------|------|------|------|------|------|------|
|        |  27  |  28  |  30  |  31  |  32  |  34  |  35  |  36  |
==================================================================
| L. PF2 | 116  | 120  | 124  | 128  | 132  | 136  | 140  | 144  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  38² |  40º |  41¹ |  42² |  44º |  45¹ |  46² |  48º |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  38º |  39¹ |  40² |  42º |  43¹ |  44² |  46º |  47¹ |
|        |------|------|------|------|------|------|------|------|
|        |  38  |  39  |  40  |  42  |  43  |  44  |  46  |  47  |
==================================================================
| R. PF0 | 148  | 152  | 156  | 160  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  49¹ |  50² |  52º |  53¹ |
|        |  - ² |  - ² |  - ² |  - ² |
|        |  48² |  50º |  51¹ |  52² |
|        |------|------|------|------|
|        |  48  |  50  |  51  |  52  |
==================================================================
| R. PF1 | 164  | 168  | 172  | 176  | 180  | 184  | 188  | 192  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  54² |  56º |  57¹ |  58² |  60º |  61¹ |  62² |  64º |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  54º |  55¹ |  56² |  58º |  59¹ |  60² |  62º |  63¹ |
|        |------|------|------|------|------|------|------|------|
|        |  54  |  55  |  56  |  58  |  59  |  60  |  62  |  63  |
==================================================================
| R. PF2 | 196  | 200  | 204  | 208  | 212  | 216  | 220  | 224  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  65¹ |  66² |  68º |  69¹ |  70² |  72º |  73¹ |  74² |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  64² |  66º |  67¹ |  68² |  70º |  71¹ |  72² |  74º |
|        |------|------|------|------|------|------|------|------|
|        |  64  |  66  |  67  |  68  |  70  |  71  |  72  |  74  |
==================================================================
```

Reflected Playfield:

```=================
| HBLANK | 000  |
|        | ÷ 3  |
|        |  00º |
|        |  - ² |
|        |  75¹ |
|        |------|
|        |  75  |
======================================
| L. PF0 | 068  | 072  | 076  | 080  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  22² |  24º |  25¹ |  26² |
|        |  - ² |  - ² |  - ² |  - ² |
|        |  22º |  23¹ |  24² |  26º |
|        |------|------|------|------|
|        |  22  |  23  |  24  |  26  |
==================================================================
| L. PF1 | 084  | 088  | 092  | 096  | 100  | 104  | 108  | 112  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  28º |  29¹ |  30² |  32º |  33¹ |  34² |  36º |  37¹ |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  27¹ |  28² |  30º |  31¹ |  32² |  34º |  35¹ |  36² |
|        |------|------|------|------|------|------|------|------|
|        |  27  |  28  |  30  |  31  |  32  |  34  |  35  |  36  |
==================================================================
| L. PF2 | 116  | 120  | 124  | 128  | 132  | 136  | 140  | 144  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  38² |  40º |  41¹ |  42² |  44º |  45¹ |  46² |  48º |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  38º |  39¹ |  40² |  42º |  43¹ |  44² |  46º |  47¹ |
|        |------|------|------|------|------|------|------|------|
|        |  38  |  39  |  40  |  42  |  43  |  44  |  46  |  47  |
==================================================================
| R. PF2 | 148  | 152  | 156  | 160  | 164  | 168  | 172  | 176  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  49¹ |  50² |  52º |  53¹ |  54² |  56º |  57¹ |  58² |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  48² |  50º |  51¹ |  52² |  54º |  55¹ |  56² |  58º |
|        |------|------|------|------|------|------|------|------|
|        |  48  |  50  |  51  |  52  |  54  |  55  |  56  |  58  |
==================================================================
| R. PF1 | 180  | 184  | 188  | 192  | 196  | 200  | 204  | 208  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  60º |  61¹ |  62² |  64º |  65¹ |  66² |  68º |  69¹ |
|        |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |  - ² |
|        |  59¹ |  60² |  62º |  63¹ |  64² |  66º |  67¹ |  68² |
|        |------|------|------|------|------|------|------|------|
|        |  59  |  60  |  62  |  63  |  64  |  66  |  67  |  68  |
==================================================================
| R. PF0 | 212  | 216  | 220  | 224  |
|        | ÷ 3  | ÷ 3  | ÷ 3  | ÷ 3  |
|        |  70² |  72º |  73¹ |  74² |
|        |  - ² |  - ² |  - ² |  - ² |
|        |  70º |  71¹ |  72² |  74º |
|        |------|------|------|------|
|        |  70  |  71  |  72  |  74  |
======================================
```

This next table is the more compacted version. I've been told that some consoles (e.g., the Coleco Gemini) have a delay of 1 full machine cycle, rather than the usual delay of 2/3 of a machine cycle, so this compacted table shows the timing values for both delays. In most cases the values are the same, due to different remainders being rounded down to the same whole value. But there are places where the values are different, and those places are marked with an asterisk.

In this last table, the first column is for a repeated playfield. The numbers after the dashes represent pixel numbers, not bit numbers. For example, "LPF0-0" means "left copy of PF0, pixel 0" (where the pixels are numbered from 0 to 7 from left to right across the screen). The second column is for a reflected playfield. The third column shows the screen position in color clocks, numbered from 0 to 159 (with HBLANK being -68 to -1). The fourth column shows the scan line position in color clocks, numbered from 0 to 227. The fifth column shows the latest machine cycle when you can update a playfield pixel and have the new value be displayed, assuming the standard delay of 2/3 of a machine cycle. The sixth column shows the latest machine cycle for nonstandard consoles where the delay is 1 machine cycle, with an asterisk by the places where this value is different than the fifth column.

```repeatd reflectd posit clock -2/3 -1
=======================================
HBLANK | HBLANK | -68 | 000 | 75 | 75
---------------------------------------
LPF0-0 | LPF0-0 | 000 | 068 | 22 | 21 *
LPF0-1 | LPF0-1 | 004 | 072 | 23 | 23
LPF0-2 | LPF0-2 | 008 | 076 | 24 | 24
LPF0-3 | LPF0-3 | 012 | 080 | 26 | 25 *
LPF1-0 | LPF1-0 | 016 | 084 | 27 | 27
LPF1-1 | LPF1-1 | 020 | 088 | 28 | 28
LPF1-2 | LPF1-2 | 024 | 092 | 30 | 29 *
LPF1-3 | LPF1-3 | 028 | 096 | 31 | 31
LPF1-4 | LPF1-4 | 032 | 100 | 32 | 32
LPF1-5 | LPF1-5 | 036 | 104 | 34 | 33 *
LPF1-6 | LPF1-6 | 040 | 108 | 35 | 35
LPF1-7 | LPF1-7 | 044 | 112 | 36 | 36
LPF2-0 | LPF2-0 | 048 | 116 | 38 | 37 *
LPF2-1 | LPF2-1 | 052 | 120 | 39 | 39
LPF2-2 | LPF2-2 | 056 | 124 | 40 | 40
LPF2-3 | LPF2-3 | 060 | 128 | 42 | 41 *
LPF2-4 | LPF2-4 | 064 | 132 | 43 | 43
LPF2-5 | LPF2-5 | 068 | 136 | 44 | 44
LPF2-6 | LPF2-6 | 072 | 140 | 46 | 45 *
LPF2-7 | LPF2-7 | 076 | 144 | 47 | 47
---------------------------------------
RPF0-0 | RPF2-0 | 080 | 148 | 48 | 48
RPF0-1 | RPF2-1 | 084 | 152 | 50 | 49 *
RPF0-2 | RPF2-2 | 088 | 156 | 51 | 51
RPF0-3 | RPF2-3 | 092 | 160 | 52 | 52
RPF1-0 | RPF2-4 | 096 | 164 | 54 | 53 *
RPF1-1 | RPF2-5 | 100 | 168 | 55 | 55
RPF1-2 | RPF2-6 | 104 | 172 | 56 | 56
RPF1-3 | RPF2-7 | 108 | 176 | 58 | 57 *
RPF1-4 | RPF1-0 | 112 | 180 | 59 | 59
RPF1-5 | RPF1-1 | 116 | 184 | 60 | 60
RPF1-6 | RPF1-2 | 120 | 188 | 62 | 61 *
RPF1-7 | RPF1-3 | 124 | 192 | 63 | 63
RPF2-0 | RPF1-4 | 128 | 196 | 64 | 64
RPF2-1 | RPF1-5 | 132 | 200 | 66 | 65 *
RPF2-2 | RPF1-6 | 136 | 204 | 67 | 67
RPF2-3 | RPF1-7 | 140 | 208 | 68 | 68
RPF2-4 | RPF0-0 | 144 | 212 | 70 | 69 *
RPF2-5 | RPF0-1 | 148 | 216 | 71 | 71
RPF2-6 | RPF0-2 | 152 | 220 | 72 | 72
RPF2-7 | RPF0-3 | 156 | 224 | 74 | 73 *
---------------------------------------
```

Michael

#### Share this post

##### Share on other sites

Here's a simpler table showing the absolute earliest and latest you can write to a playfield register in order for the new value to be displayed properly. These values should be safe regardless of whether the delay is 2/3 of a machine cycle or 1 full machine cycle.

```Asymmetrical Playfield, Repeated Graphics (PF0-PF1-PF2-PF0-PF1-PF2):

==============================================
| Playfield Register |  Earliest  |  Latest  |
==============================================
|  Left copy of PF0  | Cycle 53 * | Cycle 21 |
|  Left copy of PF1  | Cycle 64 * | Cycle 27 |
|  Left copy of PF2  | Cycle 75 * | Cycle 37 |
| Right copy of PF0  | Cycle 27   | Cycle 48 |
| Right copy of PF1  | Cycle 37   | Cycle 53 |
| Right copy of PF2  | Cycle 48   | Cycle 64 |
==============================================

Asymmetrical Playfield, Reflected Graphics (PF0-PF1-PF2-PF2-PF1-PF0):

==============================================
| Playfield Register |  Earliest  |  Latest  |
==============================================
|  Left copy of PF0  | Cycle 75 * | Cycle 21 |
|  Left copy of PF1  | Cycle 69 * | Cycle 27 |
|  Left copy of PF2  | Cycle 59 * | Cycle 37 |
| Right copy of PF2  | Cycle 48   | Cycle 48 |
| Right copy of PF1  | Cycle 37   | Cycle 59 |
| Right copy of PF0  | Cycle 27   | Cycle 69 |
==============================================

* = This refers to a cycle on the previous scan line.
```

If the left and right copies will be the same (i.e., a non-asymmetric playfield), use the cycle numbers listed for the left copies.

Note that most of the playfield registers have a good bit of leeway as to when they can be written to. The exception to this is the right copy of PF2 when drawing an asymmetrical playfield using reflected graphics-- the value for the right copy *must* be written to PF2 on cycle 48, no ifs, ands, or buts!

Michael

• 2
• 2

#### Share this post

##### Share on other sites
the value for the right copy *must* be written to PF2 on cycle 48, no ifs, ands, or buts!

Oh my. Does that mean that an asymmetrical playfield on reflected graphics is incompatible with cycle 73/74 HMOVE repositioning? If you must write to cycle 48, that means that the closest writes you could do to RESPx are cycles 45 and 51, 18 pixels apart!

Has anyone else dealt with this problem?

I don't have the cycles nor a free X to do the SAX trick (Use a repeated playfield, set X to #\$0F, do STX PF0, then load a single byte for the next PF0, and the right PF2. Use STA on PF0 and SAX on PF2.)

#### Share this post

##### Share on other sites
the value for the right copy *must* be written to PF2 on cycle 48, no ifs, ands, or buts!

Oh my. Does that mean that an asymmetrical playfield on reflected graphics is incompatible with cycle 73/74 HMOVE repositioning? If you must write to cycle 48, that means that the closest writes you could do to RESPx are cycles 45 and 51, 18 pixels apart!

Has anyone else dealt with this problem?

I don't have the cycles nor a free X to do the SAX trick (Use a repeated playfield, set X to #\$0F, do STX PF0, then load a single byte for the next PF0, and the right PF2. Use STA on PF0 and SAX on PF2.)

Two ideas come to mind. One is to use 2 lines to position the player, if needed. Another is to see if you can squeeze in a few more color clock movements to the right by doing a late HMOVE on cycle 21/22-- i.e., exactly 24 cycles after the cycle 73/74 HMOVE. (This is from a suggestion by Fred/batari, in another thread.)

Michael

## Join the conversation

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

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...