Subject: Re: Graphics Status
To: Nathan Schepers <nscheper@wincom.net>
From: Mats O Jansson <maja@cntw.com>
List: port-vax
Date: 03/31/1998 15:52:23
On Mon, 30 Mar 1998, Nathan Schepers wrote:

> 
> Gang - 
> 
> Well, I've been doing some playing with the VS2000 video stuff.  I haven't
> had that much time to spend on it because of school and everything else.
> Basic TTY stuff works, but I am still curious about a couple of
> things. 
> 
> First:  All I know about the VS2000 mono video is that there's a 1 bit per
> pixel framebuffer at 0x30000000.  I would really like some more
> information on this stuff, because using bcopy to scroll *really* sucks
> (scanline info, cursor, etc would be greatly appreciated).  Boris
> suggested that the mono video was similar to QVSS (with a reference to a
> 4.3BSD man page), and I've tried some things, but I don't think it is
> quite the same (of course, I could be wrong).  
>
> Second:  Until I know what the fate of dc.c and lk201.c are, I don't know
> whether I should rely on them to deal with keyboard & mouse.  I think
> Ragge said that dc was going to be integrated into dz, so if that's the
> case, I'll wait to do keyboard and mouse stuff.  It looks like mostly
> everything I need is in there.
> 
> Uhm, X, I guess, is next.
> 
> So, if anyone knows *anything* about any of this, please let me know. 

I think 3.5.10.4 in the following text is information about how to scroll
without moving memory.

>From VAXstation 2000 and MicroVAX 2000 Technical Manual

3.5.10 Monochrome Video Display Controller

The video display controller generates a monochrome image which is 1024
pixels wide by 864 pixels high. The controller consists of one bit-mapped
display data plane. It can superimpose a cursor at any position on the
display independently of the contents of the data plane.

3.5.10.1 Video Timing

All video timing is derived from the pixel clock crystal whose frequency
is 69.1968 MHz, which yields a pixel time of approximately 14.5 ns. The
timing of the cynchronization and blanking signals cannot be changed by a
program. Table 3-16 shows monochrome video timing.

Table 3-16: Monochrome Video Timing
----------------------------------------------------------------
Frequency Type             Frequency
----------------------------------------------------------------
Pixel			   69.1968 MHz
Horizontal                 54.06 kHz
Vertical                   60.0 Hz
----------------------------------------------------------------

----------------------------------------------------------------
Horizontal Timing	Microseconds	Pixels
----------------------------------------------------------------
Entire line		18.50		1280
Visible raster		14.80		1024
Active line time	14.798		-
Blanking		3.70		256
Sync front porch	0.173		12
Sync pulse width	1.85		128
Sync back porch		1.676		116
----------------------------------------------------------------

----------------------------------------------------------------
Vertical Timing		Milliseconds	Lines
----------------------------------------------------------------
Entire frame		16.667		901
Visible raster		15.982		864
Blanking		0.684		37
Sync front porch	0.000		0
Sync pulse width	0.055		3
Sync back porch		0.629		34
----------------------------------------------------------------

3.5.10.2 End-of-Frame Interrupt

An interrupt request is generated at the tailing edge of each vertical sync
pulse, which is three horizontal scan times after the beginning of each ver-
tical blanking interval. (The interrupt vector is listed in Section 3.5.9.4).
The time between this interrupt and the end of the vertical blanking inter-
val is approximately 620 microseconds (34 line times). Interrupts occur at
the frame rate of 60 Hz. Interrupts may be masked by clearing bit VF of
the interrupt mask register (INT_MSK) to zero (See Section 3.5.9.3). Upon
power-up, this mask bit is cleared to zero. In order for this end-of-frame
signal to be recognized as an interrupt, the VDC_SEL register (Section
3.5.9.6) must be set to select this source rather than the video option
module.

3.5.10.3 Data Plane Storage

The display data plane is stored in a 128K byte block of dual port RAM. It
occupies the physical address range 3000.0000 through 3001.FFFF. Access
to the RAM can be byte, word, or longword.

One displayed line of 1024 pixels is represented by 32 consecutive long-
words, beginning at an address whoes low-order 7 bits are all 0 (that is,
a multiple of 128 decimal). Each longword appears as 32 consecutive pixels
on a display line. Bit 0 of a longword (least significant) is displayed as
the leftmost pixel and bit 31 (most significant) is displayed as the rightmost
pixel of the 32-pixel group. Lingword addresses increases from felt to right
across a displayed line and exactly 32 longwords are required for each line.
The 128K byte data plane storage holds 1024 line images, 864 of which are
visible on the display at any one time.

NOTE: An error in the standard cell allows part of the 865th line to be
visible. To fix this problem, ensure that the 32 longwords following the
last display scan line contain 0.

3.5.10.4 Display Origin Register (VDC_ORG)

The address in the data plane storage which corresponds to the top line of
the display raster is determined by the 8-bit read/write register VDC_ORG,
whose address is 2008.000D. This register supplies bit 16:9 of the address
of the top line. Thus the address of the first longword in the topmost
displayed line is:

        Address = 3000.0000 + (VDC_ORG * 512)

The visible display can begin on any 4-line boundary and wraps from the
last line in the data plane storage (beginning at 3001.FF80) to the first
line (beginning at 3000.0000). The contents of VDC_ORG are used at the
beginning of vertical blanking interval to reset the video controller
address counter. Register VDC_ORG can be written to at any time. The
contents of VDC_ORG are cleared to 0 at power-up.

Changing VDC_ORG does not affect the displayed position of the cursor
sprite on the screen. The sprite's position register operate relative to
the first line displayed, regardless of what memory address it comes from.

...
some information skipped
...

3.6 DC503 Cursor Sprite Chip

This section describes the DC503 cursor sprite chip.

3.6.1 Overview

The DC503 cursor sprite chip generates a cursor display on the video
monitor. The cursor is generated from a two plane memory array within the
cursor chip. Refer to Section 3.5.3 for video timing and control
information. This chip is not implemented when the system module jumper is
set for MicroVAX 2000 usage. 

3.6.2 Cursor Coordinate Offset

The visible raster is 1024 pixels wide in the X direction and 864 lines
high in the Y direction. The nominal range of cursor cordinates is 0
through 1023 (left to right) and 0 through 863 (to to bottom). An offset
must be added to nominal raster cordinate value before loading the values
into the cursor position and region limits registers, because the X and Y
position counters are reset at some time prior to the beginning of the
visible display. The offset values are listed in Table 3-19.

Table 3-19: Cursor Coordinate Offsets
----------------------------------------------------------------
Offset		Value
----------------------------------------------------------------
X offset	216 pixels
Y offset	33 lines
----------------------------------------------------------------

For example, to display a sprite cursor with its upper left corner in
pixel 100, line 300, a program must load CUR_XPOS with (100 + 216) and
CUR_YPOS with (300 + 33).

3.6.3 Cursor Generation

The cursor can take two forms: a 16-bit by 16-bit pattern (sprite), or a
crosshair whose lines may extend to the edges of the visible raster or may
be clipped to a programmed region. The cursor hardware uses a DC503
programmable sprite cursor chip which generates two display planes called
the A and B planes. Bits from these planes are combined with bits from the
data plane and the possible combinations are listed in table 3-30.

Table 3-20: Cursor Generation Values
----------------------------------------------------------------
Date	A plane	B plane	Displayed	Cursor appearance
----------------------------------------------------------------
0	0	0	Black		Invisible
0	0	1	Black		Black
0	1	0	White		Inverted data
0	1	1	White		White
1	0	0	White		Invisible
1	0	1	Black		Black
1	1	0	Black		Inverted data
1	1	1	White		White
----------------------------------------------------------------

3.6.4 Cursor Control Registers

The cursor chip contains the following programmable elements:

	* Two 16-word arrays to store a 16-bit by 16-bit sprite pattern
	  for each cursor plane

	* X and Y position registers to control where the cursor pattern
	  is displayed in the raster.

	* Two region detectors, each of which defines a rectangel in the
	  raster which can be used to clip the display of a crosshair
	  cursor.

	* A control register which determines how the cursor is generated.

To a program the cursor chip appears as 12 write-only registers, each one
word (16-bits) wide. These registers should always be written with word-
access instructions; the cannot be read (hence read-modify-write
instructions such as BIS cannot be used). The register's contents after
power-u are indeterminate. The address and names of the registers are
listed in Table 3-21.

Table 3-21: Monochrome Cursor Control Registers
----------------------------------------------------------------
Address		Name		Note	Function
----------------------------------------------------------------
200F.0000	CUR_CMD			Cursor command register
200F.0004	CUR_XPOS	D	Cursor X position
200F.0008	CUR_YPOS	D	Cursor Y position
200F.000C	CUR_XMIN_1	D	Region 1 left edge
200F.0010	CUR_XMAX_1	D	Region 1 right edge
200F.0014	CUR_YMIN_1	D	Region 1 top edge
200F.0018	CUR_YMAX_1	D	Region 1 bottom edge
200F.002C	CUR_XMIN_2	D	Region 2 left edge
200F.0030	CUR_XMAX_2	D	Region 2 right edge
200F.0034	CUR_YMIN_2	D	Region 2 top edge
200F.0038	CUR_YMAX_2	D	Region 2 bottom edge
200F.003C	CUR_LOAD		Cursor sprite pattern load
----------------------------------------------------------------

In order to prevent unsightly effects on the display, the registers marked
"D" in the Note column are bufferd, as are some bits in the cursor command
register. The processor may write into such register or bit at any time
(excep within three horizontal scan times following the beginning of
vertical blanking interval. Since the processor receives its end-of-frame
interrupt signal three lines after vertical blanking begins, a program may
ensure that it has ample time to perform a multi-register update by
waiting for the end-of-frame interrupt before starting to load new values.
>From the time of the interrupt, it has nearly an entire frame time (16.612
milliseconds) to load the registers.

3.6.5 Cursor Command Register (CUR_CMD)

The cursor command register is a 16-bit write only register at address
200F.0000. An in the preceding lists of cursor registers, the bits marked
with "D" in Figure 3-55 are buffered and do not take efect until the
beginning of the next vertical blanking interval.

Figure 3-55: Cursor Command Register (CUR_CMD)

     15    14    13    12    11    10    9     8
  +-----+-----+-----+-----+-----+-----+-----+-----+-
  |TEST |HSHI |VBHI |LODSA|FORG2|ENRG2|FORG1|ENRG1|
  |     |     |     |     |     |  D  |     |  D  |
  +-----+-----+-----+-----+-----+-----+-----+-----+-

     7     6     5     4     3     2     1     0
 -+-----+-----+-----+-----+-----+-----+-----+-----+
  |XHWID|XHCL1|XHCLP|XHAIR|FOPB |ENPB |FOPA |ENPA |
  |  D  |  D  |  D  |  D  |     |  D  |     |  D  |
 -+-----+-----+-----+-----+-----+-----+-----+-----+

----------------------------------------------------------------
Data Bit	Definition
----------------------------------------------------------------
TEST		Diagnostic test (bit 15). This bit must be 1 for
		normal operation. When this bit is 0, the chip 
		is placed in test mode, which is discussed below.

HSHI		Horizontal sync polarity (bit 14). This bit must
		be 1 to indicate to the chip that the horizontal
		sync input from the video controller is active
		high.

VBHI		Vertical blanking polarity (bit 13). This bit
		must be 1 to indicate to the chip that the 
		vertical blanking input from the video is active
		high.

LODSA		Load/display sprite array (bit 12). When this bit
		is 0, the cursor sprite is displayed normally 
		from the contents of the sprite arrays. When this
		bit is 1, display of the sprite is inhibited and
		the sprite array can be loaded by successive
		writes to the CUR_LOAD register. Upon the
		transition of LODSA from 1 to 0, the internal
		array address counter is reset so that the next
		write to CUR_LOAD will load the top row of sprite
		plane A.

FORG2		Force region detector 2 output to 1 (bit 11).
		When this bit is 1, the output of region detector
		2 is forced to 1 (true). When this bit is 0, the
		detector operates normally.

ENRG2		Enable region detector 2 (bit 10). When this bit
		is 0, the output of region detector 2 is inhibited;
		it is 0 (false) unless the FORG2 bit is also set,
		which takes precedence and forces the output to 1
		(true). When ENRG2 is 1, the detector operates
		normally. 

FORG1		Force region detector 1 output to 1 (bit 9).
		When this bit is 1, the output of region detector
		1 is forced to 1 (true). When this bit is 0, the
		detector operates normally.

ENRG1		Enable region detector 1 (bit 8). When this bit
		is 0, the output of region detector12 is inhibited;
		it is 0 (false) unless the FORG1 bit is also set,
		which takes precedence and forces the output to 1
		(true). When ENRG1 is 1, the detector operates
		normally. 

XHWID		Crosshair cursor line width (bit 7). When this bit
		is 0, the crosshair cursor lines are one pixel wide.
		When this bit is 1, the lines are two pixel wide.
		The extra pixels are added to the right and below
		the pixels which lie on the lines corresponding to
		the cursor X and Y positions.

XHCLI		Select crosshair clipping region (bit 6). If this bit
		is 1. region detector 1 is used to clip the crosshair
		cursor; if it is 0 region detector 2 is used. This bit
		is effective only if the crosshair cursor is selected
		(bit XHAIR is 1) and crosshair clipping is selected
		(bit XHCLP is 1).

XHCLP		Clip crosshair inside region (bit 5). If this bit is 1,
		the crosshair cursor is clipped so that it is displayed
		only within the region selected by the XHCLI bit. If
		this bit is 0, the crosshair extend to the edges of the
		displayed raster. This bit is effective only if the
		crosshair cursor is selected (bit XHAIR is 1).

XHAIR		Crosshair/sprite cursor slect (bit 4). If this bit is
		1, the cursor chip generates a crosshair whoes lines
		intersect at the cursor X, Y positions. If this bit is
		0, the cursor chip generates the sprite pattern with its
		upper left corner at the cursor X, Y position.

FOPB		Force cursor plane B output to 1 (bit 3). When this bit
		is 1, the output from cursor plane B is forced to 1
		throughout the display, regardless of the settings of
		bits ENPB, XHAIR, XHCLP, XHCLI, XHWID, and of the contents
		of the sprite plane B array. When this bit is 0, the
		cursor is displayed normally.

ENPB		Enable cursor plane B (bit 2). When this bit is 0, the
		output from cursor plane B is inhibited; it is 0
		throughout the display. When this bit is 1, the output
		from cursor plane B is displayed normally.
 
FORA		Force cursor plane A output to 1 (bit 1). When this bit
		is 1, the output from cursor plane A is forced to 1
		throughout the display, regardless of the settings of
		bits ENPA, XHAIR, XHCLP, XHCLI, XHWID, and of the contents
		of the sprite plane A array. When this bit is 0, the
		cursor is displayed normally.

ENPA		Enable cursor plane A (bit 0). When this bit is 0, the
		output from cursor plane A is inhibited; it is 0
		throughout the display. When this bit is 1, the output
		from cursor plane A is displayed normally.

3.6.6 Loading the Cursor Sprite Pattern

The cursor sprite pattern is stored in two arrays, each made-up of sixteen
16 bit words. Each word of an array is displayed as 16 pixels on a scan
line with bit 0 (least significant) in the leftmost display position. All
32 words are loaded by writing to the CUR_LOAD register. An internal
address counter in the chip is incremented after each write to point to
the next word in the array to be loaded.

Cursor command register bit LODSA controls access to the sprite arrays.
When this bit is 0, the arrays are read during normal raster scanning to
display the sprite pattern. When LODSA is 1, normal display of the sprite
is inhibited and data can be written in to the arrays. Changing LODSA from
1 to 0 resets the internal array address counter. The next write ro
CUR_LOAD loads the top line of the A plane array; the next fifteen writes
load its remaining lines. The 16th through 32nd writes load the plane B
array from top to bottom. When loading is completed, cursor command
register bit LODSA must be reset to 0 to resume normal sprite display.

Loading the sprite arrays should be synchronized by waiting for the
end-of-frame interrupt so that loading is done during the vertical
blanking interval.

NOTE: Only writes to CUR_LOAD advances the address counter. Any of the
other registers of the cursor chip may be written to while the sprite
arrays are being loaded.

3.6.7 Cursor Region Detector

There are two region detectors, 1 and 2, each of which defines rectangular
area of the raster which can be used to clip the display of a crosshair
cursor. Each region detector is programmed by setting four registers;
CUR_XMIN, CUR_XMAX, CUR_YMIN, and CUR_YMAX. The horizontal boundaries of a
region are controlled by the the CUR_X... registers and can be specified
only to a four-pixel boundary: the least significant two bits of are
ignored and the system behaves as if thoes two bits were always 0. The
vertical boundaries are controlled by CUR_Y... registers and can be
specified to any line boundary. The offsets described in Section 3.6.2
must be applied to the values loaded into these registers.

The content of the ...MIN registers determine the leftmost picel or
topmost line in a region. The contents of the ...MAX registers determins
the first subsequent pixel or line which is no linger in the region. The
contents of a ...MAX register must always be greater than those of its
cirresponding ...MIN register.

3.6.8 Displaying a Sprite Cursor

A 16-by-16 pixel sprite cursor is displayed when cursor command register
bit XHAIR is cleared to 0. The displayed position of the upper left corner
of the sprite is controlled by the contents of the CUR_XPOS and CUR_YPOS
registers. The value loaded info these registers must include an offset as
described in Section 3.6.2. The cursor may be positioned at any pixel in
both axes and may be positioned so that part of it falls outside the
visible raster.

3.6.9 Displaying a Crosshair Cursor

A crosshair cursor is displayed when cursor command register bit XHAIR is
set to 1. This cursor consists of a vertical line and a horizontal line
which cross at the point determined by the contents of the CUR_XPOS and
CUR_YPOS registers. The value loaded into these registers must include an
offset as described in Section 3.6.2. The cursor may be positioned at any
pixel in both axes.

Cursor command register bit XHWID controls the width of the lines. If
XHWID is 0, the lines are 1 pixel wide. If XHWID is 1, the linex are
doubled in with by adding another line one pixel to the right of the
vertical line and below the horizontal line.

The length of the lines is controlled by cursor commsnd register bit
XHCLP. If XHCLP is 0, the lines extend the full width and height of the
raster. If XHCLP is 1, the lines are clipped by the region detectir
sekected by cursor command register bit XHCLI; a 1 in XHCLI relects region
1 and a 0 selects region 2.

3.6.10 Controlling Cursor Plane Output

For each cursor plane (A and B) there are two bits in the cursor commsnd
register which control each plane's output, the enable bit and the force
bit. The enable bit for plane A is ENPA and the enable bit for B is ENPB.
If either of these is 1, normal cursor data (sprite or crosshair) is
generated for the corresponding plane. If either of these is 0, the
corresponding plane output is 0. Setting both of these bits to 0
suppresses the cursor display so that screen shows only the contents of
the data plane. These bits are buffered so that they take effect only at
the start of a vertical blanking interval.

The force bit for plane A is FOPA and the force bit for plane B is FOPB.
If either of these is 1, the output of the corresponding plane is always 1
throughout the entire display raster regardkess if the state if the
plane's enable bit. The force bits are not buffered. They take effect
immediately upon loading. There bits must be 0 for normal display
operation.

3.6.11 Blanking the Display

The screen may be blanked without disturbing the display data plane or the
cursor by using the cursor plane control bits to force the output of the B
plane to 1 (set cursor command register bit FOPB) and the A plane to 0
(clear cursor control command register bit FOPA and ENPA).

3.6.12 Cursor Chip Test

The cursor chip has a test flipflop which can be used to verify that the
chip is functioning correctly. The state of this flipflop appears in bit 4
of the configuration and test register CFGTST. The value of this bit is
the complement of the flipflop output, so a flipflop value of 0 appears as
a 1 in bit 4 and vice versa.

To activate the test feature, cursor command register bit TEST must be
cleared to 0. The test flipflop is cleared to 0 whenever the cursor
command register is written to. The test flipflop is set to 1 by the
logical OR of the outputs from cursor plane A, cursor plane B, region
detector 1, and region detector 2.

Note that a test requires one full frame time to execute. A test procedure
should wait for an end-of-frame interrupt, set up the test conditions,
wait for another end-of-frame interrupt, write ri the cursor command
register to clear the test flipflop, wait for the next end-of-frame
interrupt, and then look at the test flipflop value.

3.6.13 Power-Up Initialization

Power-up initialization sets the following to true.

	* Controller select register VDC_SEL is 00h.

	* End-of-frame interrupt is masked off.

	* Display origin register VDC_ORG is 00h.

	* Cursor chip register contents are indeterminate.

	* Data plane storage contents are indeterminate.

The cursor chip requires two vertical blanking cycles to perform internal
initakization before its registers can be loaded. To provide a clean
appearance on the monitor, the startup code should wait for at least 50
milliseconds (for cursor chip internal initialization) and then set cursor
command register bits TEST, HSHI, VBHI and FOPB to 1 and clear the others.
This sets the proper sync signal polarity and blanks the screen by forcing
the B plane ouptput to 1 and the A plane output to 0.

NOTE: The cursor command register bits TEST, HSHI, and VBHI must always be
set to 1 for normal operation.


> 
> Thanks a lot,
> 
> Nathan Schepers
> (ascheper@wincom.net)
> 
> P.S. If someone wants to give me a VS3100 with all of the docs for the
> video hardware -- and pay shipping to the frozen tundra of Canada, I won't
> object. School's almost done, and I'm kind of enjoying myself with this 
> ...
> 
> 
> 

-moj

------------------------------------------------------------------------------
Mats O Jansson. Managing AIX systems at, but not speaking for:
CelsiusTech AB, Jaerfaella, Sweden. You may not add me to a commercial
mailing list or send me commercial advertising without my consent!
"Something must be wrong when a goldfish commit suicide" Godley & Creme