
		Graphics: Display generation unit
		---------------------------------
			v0.85, 2001-03-15


  The display generation unit is responsible for generating the video signal,
which is output through the "AV OUT" port on the rear side of the Dreamcast.

  Depending on where the Dreamcast has been bought, it defaults to outputting
graphics in one of four different formats: PAL, PAL-M, PAL-N, or NTSC.
  PAL and PAL-N are both 50Hz formats, whereas NTSC and PAL-M are 60Hz.
For programming purposes, PAL and PAL-M can be considered equivalent,
and NTSC and PAL-N can be considered equivalent.
  The Dreamcast can be connected to a TV using a Scart cable. An external RF
modulator gives composite output, and a VGA box allows the Dreamcast to
be connected to a commodity PC monitor.


  Image generation - overview
  ---------------------------

  Two internal counters, one each for X- and Y-position, are used to determine
where the raster beam is located. One field looks like this:

    0
  0 +--------------------------------------------------------------------> X
    |VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
    |VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
    |HHHHS
    |HHHH   ...........................................................
    |HHHH   ...........................................................
    |HHHH   ...........................................................
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   .....**************************************************....
    |HHHH   ...........................................................
    |HHHH   ...........................................................
    |HHHH   ...........................................................
    |HHHH
    v

	V = Vertical retrace in progress
	H = horizontal retrace in progress
	. = Border-colour window is visible
	* = Framebuffer window is visible

  In 640 x 480 x 60Hz (VGA resolution), the above graph would be roughly
850 x 525 units large.

  The position marked with an 'S' is where the video beam has reached the
upper-left corner of the monitor, and is about to begin another re-draw
of the screen.

  The border-colour is window filled with the color that is chosen as
background colour, while the framebuffer window is filled with pixel data
from graphics memory. The framebuffer window is in front of the
background-colour window. Outside both windows, black is emitted.
  Both windows can be positioned independently. Normally, the border-colour
window is made large enough to cover the entire visible screen area, and
the framebuffer window a bit smaller than that (to make sure that the entire
bitmap window is visible on all monitors (different monitors may vary slightly
in where the image is displayed)).

  In interlaced screenmodes, one frame is made up of two fields. The image
is displayed on the monitor, by re-drawing the screen twice; the first pass
redraws the even lines, and the second pass redraws the odd lines.
An interlaced 60Hz resolution displays 60 _fields_ per second, which results
in 30 _frames_ per second.
  In non-interlaced screenmodes, one frame is made up of one field.
  15kHz TVs can only display images with about 250-280 lines without
interlace; with interlace, the number doubles.
(Because NTSC/PAL resolutions have 525/625 lines per frame, the first field
 will contain one more line than the second, hence the names "long field"
 and "short field".)


  Image generation - details
  --------------------------

  The hardware supplies a 37ns (roughly 27MHz) pixel clock. All timings
are made against that clock. If high clock speed is not enabled,
the clock speed will be halved, down to 13.5MHz (74ns). Halved clock is
used when displaying 15kHz modes.

  Number of clocks per line, and number of lines per field, can be set
independently. Normal values for an NTSC resolution are approximately
850 clocks per line, and 262 lines per field.
The number of clocks per line, and number of lines per field, determine
the refresh rate of the mode; with our example figures, processing
one frame takes 850 * 262 * 74ns, which would result in a refresh rate
of roughly 60Hz.

  Vertical retrace is active during lines 0 through 4 of each field.
  Horizontal retrace is active from clock 0 of each line. (I don't have
any figure of how long it is active... perhaps about 20 cycles?)

  The framebuffer window can contain pixel data in either RGB555, RGB565,
RGB888 or ARGB8888 format. So far, I have not succeeded in properly
setting up any RGB888 mode though.
  Modulo is supported (skipping a given number of bytes between
each scanline); pixels can be widened to twice their usual width
horizontally (pixel-doubling), and lines can be repeated twice
vertically (line-doubling).



  Programming the image generation unit: 640x480x60Hz interlace
  -------------------------------------------------------------

  Normally, both PAL and NTSC TVs can display this resolution.
  
  This example will set up a 640x480x60Hz interlace resolution with an
RGB565 framebuffer.

  The NTSC video standard specifies 525 lines/frame, 15750 lines/second,
30 frames/second (60 fields/second).
  525 lines/frame * 30 frames/second * 74ns/clock gives a figure of
0.0011655 lines/clock, or - inversely - 858 clocks/line. We will thus
have a frame which is 858 clocks by 525 lines. (So each field will be
858 clocks by 262.5 lines (long field 263, short field 262).)

  Set the number of clocks per line (858), and number of lines per
frame (525), in FRAMETOTAL.

  All other registers will only contain per-field specifications, so
from now on we will only work with Y-coordinates in the
interval 0 through 262.

  Once we know the size of the frame, we can consider what coordinates
to give the border-colour window. Reasonable values for X-start and
X-stop are 128 and 837 (goes into BORDERWINDOWX); Y-start and Y-stop
can be set to 18 and 258 (goes into BORDERWINDOWY). Colour of the
window goes into BORDERCOLOR, specified as a 32-bit ARGB8888 value.

  The upper-left corner of the display window is reasonably placed
at (164, 18) (goes into DIWSTARTH and DIWSTARTV). Notice that in
DIWSTARTV it is possible to specify two values; one value will be
used for the long field, and the other for the short field.

  Size of the display window is controlled by the DIWSIZE register;
number of rows is 240, since each field only will display every
other line. Modulo is 640*2 bytes, since after having displayed
one line of pixels from the framebuffer, the pixel data of the next
line should be skipped over (it will be displayed in the next field
instead). Line length is specified as the total number of bytes that
will be read from the framebuffer when displaying one full line --
640*2 bytes.

  The start address where the framebuffer window will begin to read
pixel data from graphics memory is specified in FRAMEBUF (long frame)
and FRAMEBUF2 (short frame). Set FRAMEBUF to the base address of 
the region you want to display, and FRAMEBUF2 one line into the
region.

  Some mode configuration registers also need to be set, mainly
the BITMAPTYPE* registers:

  BITMAPTYPE should have VGA mode disabled, line doubling disabled,
and bitmap display enabled. Display mode should be RGB565.

  BITMAPTYPE2 should have horizontal pixel doubling disabled,
and interlace-half-line-step-down enabled.

  IMAGECONTROL should have 50Hz interlace disabled, 60Hz interlace enabled,
  and interlace enabled.
  
  A few other registers must have appropriate contents in order for
the resolution to work reliably, but it has not yet been determined
exactly what those registers do. The BootROM code leaves
those registers in reasonable states though.


  Programming the image generation unit: 640x480x50Hz interlace
  -------------------------------------------------------------

Normally, only PAL TVs can display this resolution.
  
This is set up similarly to 640x480x60Hz interlace with RGB565 framebuffer.

The PAL video standard specifies 625 lines/frame, 15625 lines/second,
25 frames/second (50 fields/second).

  625 lines/frame * 25 frames/second * 74ns/clock gives a figure of
0.0011655 lines/clock, or - inversely - approx. 864 clocks/line.
We will thus have a frame which is 864 clocks by 625 lines.
(So each field will be 864 clocks by 312.5 lines (long field 313,
short field 312).)

FRAMETOTAL - number of clocks per line 864, number of lines per frame 625
BORDERWINDOWX - X-start 136, X-stop 843
BORDERWINDOWY - Y-start 22, Y-stop 308
DIWSTARTH - 176
DIWSTARTV - long field 44, short field 45 (beware!)
DIWSIZE - number of rows 240, modulo 640*2 bytes, row length 640*2 bytes
FRAMEBUF - base address of screen, first line in memory
FRAMEBUF2 - base address of screen, second line in memory
BITMAPTYPE - VGA mode disabled, line doubling disabled, bitmap enabled, RGB565
BITMAPTYPE2 - horizontal pixel doubling disabled, bitmap disable disabled,
	      interlace-half-line-step-down enabled
IMAGECONTROL - 60Hz interlace disabled, 50Hz interlace enabled,
	       interlace enabled
	      
  
  What about Composite/Scart/VGA compatibility?
  ---------------------------------------------

  It is possible to check which kind of cable is being used by reading
bits 8-9 of register PDTRA in the CPU.
  If a composite cable is being used, 3<<8 should be written to 0xa0702c00,
otherwise anything else. This is done by the BootROM code, so
Composite/Scart/VGA should work flawlessly without programming that
register.

  What about PAL/NTSC/VGA compatibility?
  --------------------------------------

  VGA resolutions usually have a horizontal frequency of approximately 31kHz,
whereas TVs have a horizontal frequency of 15kHz. Therefore, VGA and TV
modes are not compatible. PAL equipment often (but not always) handles 60Hz
resolutions; NTSC equipment is worse at handling 50Hz resolutions.

  In order to check which kind of equipment one is running on, first check
if a VGA cable is attached (check PDTRA). If not, call the BootROM
via the entry point vector at 0x8c0000b0, with r7 = 3; in the returned
structure, there is an ID byte which specifies which one
of PAL/PAL-N/PAL-M/NTSC video signals are supported by the Dreamcast.
A well-behaved program should default to PAL/NTSC/VGA mode depending on the
result of the above checks.

  A "fullscreen" image in 50Hz is 640x512 pixels; in 60Hz it
is 640x480 pixels.


  Unknown things
  --------------

  A few registers have not yet been figured out.
  libdream contains an 800x608 mode: from the above description,
it seems to be a 48Hz mode?
  What is register 0xa0702c00 really doing?

