Video timings

Interesting info from linux 2.4 kernel sources (drivers/video/amifb.c).

   Generic video timings
   ---------------------

   Timings used by the frame buffer interface:

   +----------+---------------------------------------------+----------+-------+
   |          |                ^                            |          |       |
   |          |                |upper_margin                |          |       |
   |          |                Ľ                            |          |       |
   +--------------------+-------+
   |                          ^                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |   left                   |                              right   | hsync |
   |  margin                  |       xres                   margin  |  len  |
   |<--------><---------------+---------------------------><-------->|<----->|
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |yres                                  |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          |                                      |       |
   |                          Ľ                                      |       |
   +--------------------+-------+
   |          |                ^                            |          |       |
   |          |                |lower_margin                |          |       |
   |          |                Ľ                            |          |       |
   +----------+---------------------------------------------+----------+-------+
   |          |                ^                            |          |       |
   |          |                |vsync_len                   |          |       |
   |          |                Ľ                            |          |       |
   +----------+---------------------------------------------+----------+-------+


   Amiga video timings
   -------------------

   The Amiga native chipsets uses another timing scheme:

      - hsstrt:   Start of horizontal synchronization pulse
      - hsstop:   End of horizontal synchronization pulse
      - htotal:   Last value on the line (i.e. line length = htotal+1)
      - vsstrt:   Start of vertical synchronization pulse
      - vsstop:   End of vertical synchronization pulse
      - vtotal:   Last line value (i.e. number of lines = vtotal+1)
      - hcenter:  Start of vertical retrace for interlace

   You can specify the blanking timings independently. Currently I just set
   them equal to the respective synchronization values:

      - hbstrt:   Start of horizontal blank
      - hbstop:   End of horizontal blank
      - vbstrt:   Start of vertical blank
      - vbstop:   End of vertical blank

   Horizontal values are in color clock cycles (280 ns), vertical values are in
   scanlines.

   (0, 0) is somewhere in the upper-left corner :-)


   Amiga visible window definitions
   --------------------------------

   Currently I only have values for AGA, SHRES (28 MHz dotclock). Feel free to
   make corrections and/or additions.

   Within the above synchronization specifications, the visible window is
   defined by the following parameters (actual register resolutions may be
   different; all horizontal values are normalized with respect to the pixel
   clock):

      - diwstrt_h:   Horizontal start of the visible window
      - diwstop_h:   Horizontal stop+1(*) of the visible window
      - diwstrt_v:   Vertical start of the visible window
      - diwstop_v:   Vertical stop of the visible window
      - ddfstrt:     Horizontal start of display DMA
      - ddfstop:     Horizontal stop of display DMA
      - hscroll:     Horizontal display output delay

   Sprite positioning:

      - sprstrt_h:   Horizontal start-4 of sprite
      - sprstrt_v:   Vertical start of sprite

   (*) Even Commodore did it wrong in the AGA monitor drivers by not adding 1.

   Horizontal values are in dotclock cycles (35 ns), vertical values are in
   scanlines.

   (0, 0) is somewhere in the upper-left corner :-)


   Dependencies (AGA, SHRES (35 ns dotclock))
   -------------------------------------------

   Since there are much more parameters for the Amiga display than for the
   frame buffer interface, there must be some dependencies among the Amiga
   display parameters. Here's what I found out:

      - ddfstrt and ddfstop are best aligned to 64 pixels.
      - the chipset needs 64+4 horizontal pixels after the DMA start before the
        first pixel is output, so diwstrt_h = ddfstrt+64+4 if you want to
        display the first pixel on the line too. Increase diwstrt_h for virtual
        screen panning.
      - the display DMA always fetches 64 pixels at a time (fmode = 3).
      - ddfstop is ddfstrt+pixels-64.
      - diwstop_h = diwstrt_h+xres+1. Because of the additional 1 this can be 1
        more than htotal.
      - hscroll simply adds a delay to the display output. Smooth horizontal
        panning needs an extra 64 pixels on the left to prefetch the pixels that
        `fall off' on the left.
      - if ddfstrt < 192, the sprite DMA cycles are all stolen by the bitplane
        DMA, so it's best to make the DMA start as late as possible.
      - you really don't want to make ddfstrt < 128, since this will steal DMA
        cycles from the other DMA channels (audio, floppy and Chip RAM refresh).
      - I make diwstop_h and diwstop_v as large as possible.

   General dependencies
   --------------------

      - all values are SHRES pixel (35ns)

                  table 1:fetchstart  table 2:prefetch    table 3:fetchsize
                  ------------------  ----------------    -----------------
   Pixclock      SHRES|HIRES|LORES  SHRES|HIRES|LORES  SHRES|HIRES|LORES
   -------------------+-----+------------+-----+------------+-----+------
   Bus width 1x    16 |  32 |  64     16 |  32 |  64     64 |  64 |  64
   Bus width 2x    32 |  64 | 128     32 |  64 |  64     64 |  64 | 128
   Bus width 4x    64 | 128 | 256     64 |  64 |  64     64 | 128 | 256

      - chipset needs 4 pixels before the first pixel is output
      - ddfstrt must be aligned to fetchstart (table 1)
      - chipset needs also prefetch (table 2) to get first pixel data, so
        ddfstrt = ((diwstrt_h-4) & -fetchstart) - prefetch
      - for horizontal panning decrease diwstrt_h
      - the length of a fetchline must be aligned to fetchsize (table 3)
      - if fetchstart is smaller than fetchsize, then ddfstrt can a little bit
        moved to optimize use of dma (useful for OCS/ECS overscan displays)
      - ddfstop is ddfstrt+ddfsize-fetchsize
      - If C= didn't change anything for AGA, then at following positions the
        dma bus is allready used:
        ddfstrt <  48 -> memory refresh
                <  96 -> disk dma
                < 160 -> audio dma
                < 192 -> sprite 0 dma
                < 416 -> sprite dma (32 per sprite)
      - in accordance with the hardware reference manual a hardware stop is at
        192, but AGA (ECS?) can go below this.

   DMA priorities
   --------------

   Since there are limits on the earliest start value for display DMA and the
   display of sprites, I use the following policy on horizontal panning and
   the hardware cursor:

      - if you want to start display DMA too early, you loose the ability to
        do smooth horizontal panning (xpanstep 1 -> 64).
      - if you want to go even further, you loose the hardware cursor too.

   IMHO a hardware cursor is more important for X than horizontal scrolling,
   so that's my motivation.


   Implementation
   --------------

   ami_decode_var() converts the frame buffer values to the Amiga values. It's
   just a `straightforward' implementation of the above rules.


   Standard VGA timings
   --------------------

               xres  yres    left  right  upper  lower    hsync    vsync
               ----  ----    ----  -----  -----  -----    -----    -----
      80x25     720   400      27     45     35     12      108        2
      80x30     720   480      27     45     30      9      108        2

   These were taken from a XFree86 configuration file, recalculated for a 28 MHz
   dotclock (Amigas don't have a 25 MHz dotclock) and converted to frame buffer
   generic timings.

   As a comparison, graphics/monitor.h suggests the following:

               xres  yres    left  right  upper  lower    hsync    vsync
               ----  ----    ----  -----  -----  -----    -----    -----

      VGA       640   480      52    112     24     19    112 -      2 +
      VGA70     640   400      52    112     27     21    112 -      2 -


   Sync polarities
   ---------------

      VSYNC    HSYNC    Vertical size    Vertical total
      -----    -----    -------------    --------------
        +        +           Reserved          Reserved
        +        -                400               414
        -        +                350               362
        -        -                480               496

   Source: CL-GD542X Technical Reference Manual, Cirrus Logic, Oct 1992


   Broadcast video timings
   -----------------------

   According to the CCIR and RETMA specifications, we have the following values:

   CCIR -> PAL
   -----------

      - a scanline is 64 ľs long, of which 52.48 ľs are visible. This is about
        736 visible 70 ns pixels per line.
      - we have 625 scanlines, of which 575 are visible (interlaced); after
        rounding this becomes 576.

   RETMA -> NTSC
   -------------

      - a scanline is 63.5 ľs long, of which 53.5 ľs are visible.  This is about
        736 visible 70 ns pixels per line.
      - we have 525 scanlines, of which 485 are visible (interlaced); after
        rounding this becomes 484.

   Thus if you want a PAL compatible display, you have to do the following:

      - set the FB_SYNC_BROADCAST flag to indicate that standard broadcast
        timings are to be used.
      - make sure upper_margin+yres+lower_margin+vsync_len = 625 for an
        interlaced, 312 for a non-interlaced and 156 for a doublescanned
        display.
      - make sure left_margin+xres+right_margin+hsync_len = 1816 for a SHRES,
        908 for a HIRES and 454 for a LORES display.
      - the left visible part begins at 360 (SHRES; HIRES:180, LORES:90),
        left_margin+2*hsync_len must be greater or equal.
      - the upper visible part begins at 48 (interlaced; non-interlaced:24,
        doublescanned:12), upper_margin+2*vsync_len must be greater or equal.
      - ami_encode_var() calculates margins with a hsync of 5320 ns and a vsync
        of 4 scanlines

   The settings for a NTSC compatible display are straightforward.

   Note that in a strict sense the PAL and NTSC standards only define the
   encoding of the color part (chrominance) of the video signal and don't say
   anything about horizontal/vertical synchronization nor refresh rates.


                                                            -- Geert --

*******************************************************************************/

/*
 * Since we can't read the palette on OCS/ECS, and since reading one
 * single color palette entry requires 5 expensive custom chip bus accesses
 * on AGA, we keep a copy of the current palette.
 * Note that the entries are always 24 bit!
 */



/*
 * Macros for the conversion from real world values to hardware register
 * values
 *
 * This helps us to keep our attention on the real stuff...
 *
 * Hardware limits for AGA:
 *
 *parameter  min    max  step
 *---------  ---   ----  ----
 *diwstrt_h    0   2047     1
 *diwstrt_v    0   2047     1
 *diwstop_h    0   4095     1
 *diwstop_v    0   4095     1
 *
 *ddfstrt      0   2032    16
 *ddfstop      0   2032    16
 *
 *htotal       8   2048     8
 *hsstrt       0   2040     8
 *hsstop       0   2040     8
 *vtotal       1   4096     1
 *vsstrt       0   4095     1
 *vsstop       0   4095     1
 *hcenter      0   2040     8
 *
 *hbstrt       0   2047     1
 *hbstop       0   2047     1
 *vbstrt       0   4095     1
 *vbstop       0   4095     1
 *
 * Horizontal values are in 35 ns (SHRES) pixels
 * Vertical values are in half scanlines
 */

Interesting links: