aboutsummaryrefslogtreecommitdiff
path: root/pkg/images/tv/iis/ids/doc
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/images/tv/iis/ids/doc
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'pkg/images/tv/iis/ids/doc')
-rw-r--r--pkg/images/tv/iis/ids/doc/Imdis.hlp793
-rw-r--r--pkg/images/tv/iis/ids/doc/Note.misc8
-rw-r--r--pkg/images/tv/iis/ids/doc/Note.pixel106
-rw-r--r--pkg/images/tv/iis/ids/doc/file.doc90
-rw-r--r--pkg/images/tv/iis/ids/doc/iis.doc172
5 files changed, 1169 insertions, 0 deletions
diff --git a/pkg/images/tv/iis/ids/doc/Imdis.hlp b/pkg/images/tv/iis/ids/doc/Imdis.hlp
new file mode 100644
index 00000000..0ddd46e5
--- /dev/null
+++ b/pkg/images/tv/iis/ids/doc/Imdis.hlp
@@ -0,0 +1,793 @@
+.help imdis Dec84 "Image Display I/O"
+.ce
+\fBImage display I/O Design\fR
+.ce
+Richard Wolff
+.ce
+May 1985
+.sp 1
+.nh
+Introduction
+
+ The image display i/o interface uses the features of the GIO interface
+to provide for the reading and writing of images and for the control of
+the various subunits of a typical image display device. The cell array
+calls of GIO are used for the image data, while the text and polyline
+functions handle the text and line generation. Cursor reads are also
+done with standard GIO calls. However, all the other display functions
+are implemented through a series of GIO escape sequences, which are
+described in this document.
+.sp
+.nh
+Escape sequences
+
+ Each sequence is described here, giving first a line with the count
+of the number of words in the escape "instruction", followed by the data.
+Since most of the data items might be more rationally considered arrays,
+they are so indicated here. This means that in most cases, the number of
+words in the escape instruction cannot be determined until run-time; an
+indication of this is the use of "sizeof(arrays)" to indicate the number
+of words in all the pseudo arrays.
+.sp
+Escape 10 -- reset
+.ls
+.tp 5
+1 hard/medium/soft
+.ls
+.nf
+hard Clear image and graphics planes
+medium reset all (lookup) tables to linear
+soft reset scroll, zoom, cursor, alu, etc.
+.fi
+.le
+.le
+.sp
+This sequence is used to preform various reset commands. These are not
+done at GKOPENWS time because the user will not necessarily want to
+upset the existing display when the image kernel is started up.
+.sp
+Escape 11 -- set image plane
+.ls
+.tp 4
+sizeof(arrays) IFA IBPL
+.ls
+.nf
+IFA(i) image frame array
+IBPL(i) image bit plane array
+.fi
+.le
+.le
+.sp
+This sequence is essentially a header to the getcell/putcell calls. It
+identifies both the frame(s) and bit plane(s) to be read or written. IFA
+is an array of (short) integers, each of which specifies a plane (using
+one indexing), the last element of the array being the integer IDS_EOD
+to flag the End Of Data. IDS_EOD is a defined to be (-2). IBPL represents
+the bit planes that are to be read or written for all the frames in IFA.
+The data is IBPL is terminated with IDS_EOD. If the first element of IFA (or
+IBPL) is IDS_EOD, all image frames (all bit planes) are involved in the I/O.
+All "array" data are expected to be terminated with IDS_EOD, and the general
+convention is maintained that IDS_EOD with no preceding data implies all
+"frames", "colors", or whatever.
+.sp
+Escape 12 -- set graphics plane
+.ls
+.tp 4
+sizeof(arrays) GFA GBPL
+.ls
+.nf
+GFA(i) graphics frame array
+GBPL(i) graphics bit plane array
+.fi
+.le
+.le
+.sp
+This sequence is identical to escape 11, but refers to graphics planes
+instead of image planes. Generally, each graphics bit plane will refer to
+a particular color, or perhaps, to a particular image plane. But there is
+no enforced correspondence between graphics planes and image planes or colors.
+The GFA specifies a set of graphics planes, and is probably unnecessary as the
+bitplane array carries adequate information. Including it, however, retains
+symmetry with escape 11. Thus, GFA cannot be omitted, for otherwise the
+kernel would not know where GBPL started, but is set to IDS_EOD, and the
+kernel can then find and ignore it.
+.sp
+Escape 13 -- display image
+.ls
+.tp 6
+1+sizeof(arrays) ON/OFF IFA ICOLOR IQUAD
+.ls
+.nf
+ON/OFF turn frame on or off
+IFA(i) image frame array
+ICOLOR(i) image color array
+IQUAD(i) image quadrant array (for split screen mode)
+.fi
+.le
+.le
+.sp
+The specified image planes are all to be displayed in all the colors given
+by ICOLOR. If ICOLOR(1) is IDS_EOD, a full color display is implied.
+The quadrant value specifies which quadrant the frames are
+to appear in--this is needed only when the split screen mode is in effect;
+otherwise, IQUAD[1] = IDS_EOD.
+.sp
+Escape 14 -- display graphics
+.ls
+.tp 6
+1+sizeof(arrays) ON/OFF GBPL GCOLOR GQUAD
+.ls
+.nf
+ON/OFF turn referenced planes on or off
+GBPL(i) graphics bit plane array
+GCOLOR(i) graphics color array
+GQUAD(i) graphics quadrant array (for split screen mode)
+.fi
+.le
+.le
+.sp
+This sequence is identical to escape 13, except for the substitution of
+a bitplane array for frames, since graphics are usually treated bit by bit.
+[With the IIS systems, for instance, this call requires manipulation of
+the color-graphics lookup table.]
+.sp
+Escape 15 -- save device state
+.ls
+.tp 5
+1+sizeof(arrays) FD IFA GFA
+.ls
+.nf
+FD file descriptor for save file
+IFA(i) image frame array
+GFA(i) graphics frame array
+.fi
+.le
+.le
+.sp
+Saves the specified image frames and graphics planes and all the device
+dependent status information in the file referenced by FD. Not implemented
+in the Kernel (yet).
+.sp
+Escape 16 -- restore device state
+.ls
+.tp 5
+1+sizeof(arrays) FD IFA GFA
+.ls
+.nf
+FD file descriptor for restore file
+IFA(i) image frame array
+GFA(i) graphics frame array
+.fi
+.le
+.le
+.sp
+Restores the specified image frames and graphics planes and all the device
+dependent status information from the file referenced by FD. Not implemented
+in the Kernel (yet).
+.sp
+Escape 17 -- control
+.ls
+.tp 9
+4+sizeof(arrays) REG RW N FRAME COLOR OFFSET DATA
+.ls
+.nf
+REG(i) control register or function
+RW(i) read or write (write is 0, read 1, wait/read is 2)
+N(i) Number of data values
+FRAME(i) frame array
+COLOR(i) color array
+OFFSET(i) offset or other datum
+DATA(Ni) array of data
+.fi
+.le
+.le
+.sp
+Escape 18 is a very general sequence for writing any device
+control register. Such "registers" include such generally available
+capabilities as look-up tables, as well as specifics, such as min/max
+registers. The upper level code may have to consult an "imagecap"
+file to determine what it can request.
+
+FRAME, OFFSET, and COLOR, may not be needed for a particular operation,
+but these arrays cannot be omitted; rather, use a one element array with
+the value IDS_EOD. Should additional information be needed for an operation,
+it can be transmitted in DATA.
+.sp
+.nh
+Examples
+
+.sp
+To clear all frames, one would issue the following sequence
+.ls
+.tp 4
+.nf
+GKI_ESCAPE 11 IFA[1] = IDS_EOD IBPL[1] = IDS_EOD
+GKI_CLEARWS
+GKI_ESCAPE 12 IFA[1] = IDS_EOD IBPL[1] = IDS_EOD
+GKI_CLEARWS
+.fi
+.le
+.sp
+To write an image to frame 2 ( IIS internal frame number 1 )
+.ls
+.tp 2
+.nf
+GKI_ESCAPE 11 IFA[1] = 2 IFA[2] = IDS_EOD IBPL[1] = IDS_EOD
+GKI_PCELL data
+.fi
+.le
+.sp
+To activate frame 1 in red and green
+.ls
+.tp 2
+.nf
+GKI_ESCAPE 13 IFA[1] = 1 IFA[2] = IDS_EOD ICOLOR[1] = IDS_RED
+ ICOLOR[2] = IDS_GREEN ICOLOR[3] = IDS_EOD
+ IQUAD[1] = IDS_EOD
+.fi
+.le
+.sp
+.bp
+.nh
+Defines
+
+This section presents the value and intended use of each of the various
+defined constants. This list is likely to expand.
+
+.nf
+define IDS_EOD (-2) # flag for end of data
+
+define IDS_RESET 10 # escape 10
+define IDS_R_HARD 0 # hard reset
+define IDS_R_MEDIUM 1 # medium
+define IDS_R_SOFT 2
+define IDS_R_SNAPDONE 3 # end snap
+
+define IDS_SET_IP 11 # escape 11
+define IDS_SET_GP 12 # escape 12
+define IDS_DISPLAY_I 13 # escape 13
+define IDS_DISPLAY_G 14 # escape 14
+define IDS_SAVE 15 # escape 15
+define IDS_RESTORE 16 # escape 16
+
+# max sizes
+
+define IDS_MAXIMPL 16 # maximum number of image planes
+define IDS_MAXGRPL 16 # maximum number of graphics planes
+define IDS_MAXBITPL 16 # maximum bit planes per frame
+define IDS_MAXGCOLOR 8 # maximum number of colors (graphics)
+define IDS_MAXDATA 8192 # maximum data structure in display
+
+define IDS_RED 1
+define IDS_GREEN 2
+define IDS_BLUE 3
+define IDS_YELLOW 4
+define IDS_RDBL 5
+define IDS_GRBL 6
+define IDS_WHITE 7
+define IDS_BLACK 8
+
+define IDS_QUAD_UR 1 # upper right quad.: split screen mode
+define IDS_QUAD_UL 2
+define IDS_QUAD_LL 3
+define IDS_QUAD_LR 4
+
+define IDS_CONTROL 17 # escape 17
+define IDS_CTRL_LEN 6
+define IDS_CTRL_REG 1 # what to control
+define IDS_CTRL_RW 2 # read/write field in control instr.
+define IDS_CTRL_N 3 # count of DATA items
+define IDS_CTRL_FRAME 4 # pertinent frame(s)
+define IDS_CTRL_COLOR 5 # and color
+define IDS_CTRL_OFFSET 6 # generalized "register"
+define IDS_CTRL_DATA 7 # data array
+
+define IDS_WRITE 0 # write command
+define IDS_READ 1 # read command
+define IDS_READ_WT 2 # wait for action, then read
+define IDS_OFF 1 # turn whatever off
+define IDS_ON 2
+define IDS_CBLINK 3 # cursor blink
+define IDS_CSHAPE 4 # cursor shape
+
+define IDS_CSTEADY 1 # cursor blink - steady (no blink)
+define IDS_CFAST 2 # cursor blink - fast
+define IDS_CMEDIUM 3 # cursor blink - medium
+define IDS_CSLOW 4 # cursor blink - slow
+
+define IDS_FRAME_LUT 1 # look-up table for image frame
+define IDS_GR_MAP 2 # graphics color map...lookup table per
+ # se makes little sense for bit plane
+define IDS_INPUT_LUT 3 # global input lut
+define IDS_OUTPUT_LUT 4 # final lut
+define IDS_SPLIT 5 # split screen coordinates
+define IDS_SCROLL 6 # scroll coordinates
+define IDS_ZOOM 7 # zoom magnification
+define IDS_OUT_OFFSET 8 # output bias
+define IDS_MIN 9 # data minimum
+define IDS_MAX 10 # data maximum
+define IDS_RANGE 11 # output range select
+define IDS_HISTOGRAM 12 # output data histogram
+define IDS_ALU_FCN 13 # arithmetic feedback function
+define IDS_FEEDBACK 14 # feedback control
+define IDS_SLAVE 15 # auxiliary host or slave processor
+
+define IDS_CURSOR 20 # cursor control - on/off/blink/shape
+define IDS_TBALL 21 # trackball control - on/off
+define IDS_DIGITIZER 22 # digitizer control - on/off
+
+define IDS_BLINK 23 # for blink request
+define IDS_SNAP 24 # snap function
+define IDS_MATCH 25 # match lookup tables
+
+# snap codes ... just reuse color codes from above.
+define IDS_SNAP_RED IDS_RED # snap the blue image
+define IDS_SNAP_GREEN IDS_GREEN # green
+define IDS_SNAP_BLUE IDS_BLUE # blue
+define IDS_SNAP_RGB IDS_BLACK # rgb image --- do all three
+define IDS_SNAP_MONO IDS_WHITE # do just one
+
+# cursor parameters
+
+define IDS_CSET 128 # number of cursors per "group"
+
+define IDS_CSPECIAL 4097 # special "cursors"
+ # must be > (IDS_CSET * number of cursor groups)
+define IDS_CRAW IDS_CSPECIAL # raw cursor read
+define IDS_BUT_RD 4098 # "cursor number" for read buttons cmd
+define IDS_BUT_WT 4099 # wait for button press, then read
+define IDS_CRAW2 4100 # a second "raw" cursor
+.fi
+.nh
+Explanation
+
+ Most of the control functions of an image display do not fit within
+the standard GIO protocols, which is why the escape function is provided.
+However, image displays exhibit a wide range of functionality, and some
+balance must be achieved between code portability/device independence and
+use of (possibly peculiar) capabilities of a particular device. The control
+functions (such as IDS_FRAME_LUT, IDS_CURSOR, IDS_SLAVE) "selected" here
+are, for the most part, general functions, but the code was written with
+the IIS Model 70 at hand (and in mind), and some "defines" reflect this.
+
+ The model of the display is a device with some number of image frames,
+each of which has associated with it an INPUT look-up table, used for
+scaling or bit selection as data is written into the image frame;
+a FRAME look-up table for each of the three primary colors, used to
+alter the video stream from the image frame; combining logic that sums the
+output of the various FRAME tables, forming three data streams, one for
+each color; an OUTPUT look-up table that forms a final transformation
+on each color prior to the data being converted to analog form; and
+possibly, bias (OUT_OFFSET) and RANGE scaling applied somewhere in the
+data stream (most likely near the OUTPUT look-up tables).
+
+ Each image plane can be SCROLLed and ZOOMed independently (though
+of course, not all devices can do this), and there may be SPLIT screen
+capability, with the possibility of displaying parts of four images
+simultaneously.
+
+ Hooks have been provided in case there is a ALU or FEEDBACK hardware,
+or there is a SLAVE processor, but use of these functions is likely to
+be quite device dependent. The IIS can return to the user the MINimum
+and MAXimum of a color data stream, and can also run a histogram on
+selected areas of the display: There are "defines" pointing to these
+functions, but their use is not yet specified and there is not yet
+a clean way, within the GIO protocols, for reading back such data.
+
+ Three functions that not so hardware oriented have "defines":
+BLINK, MATCH and SNAP. The first is used if the hardware supports
+blink. MATCH allows the kernel code to copy look-up tables---something
+the upper level code could do were there a well defined mechanism for
+reading non-image data back. SNAP is used to set-up the kernel so that
+a subsequent set of get_cellarray calls can be used to return a data
+stream that represents the digital data arriving at the
+digital-to-analog converters: the kernel mimics the hardware and so
+provides a digital snapshot of the image display screen.
+
+ Images are loaded by a series of put_cellarray calls, preceded
+by one IDS_SET_IP escape to configure the kernel to write the put_cell
+data into the correct image planes (and optionally, specific bit planes).
+The graphics planes are written to in the same manner, except that
+IDS_SET_GP is used. It is not guaranteed that the SET_IP and SET_GP
+are independent, and so the appropriate one should be given before
+each put_cell sequence. Put_cells can be done for any arbitrary
+rectangular array; they are turned into a series of writes to a
+sequence of image rows by the GIO interface code.
+
+ Calls to put_cell require the mapping of pixel coordinates
+to NDC, which is made more complex than one might first
+guess by the fact that the cell array operations are specified
+by *inclusive* end points...See the write-up in "Note.pixel".
+
+ Images planes are erased by the standard GIO gclear call, which
+must be preceded by a SET_IP (or SET_GP for graphics). This is
+perceived as reasonably consistent with the image loading as erasure
+is loading with zeros, but presumably can be done far more efficiently
+in most devices than with a series of put_cell calls.
+
+ Images planes are turned on and off with IDS_DISPLAY_I, and graphics
+planes with IDS_DISPLAY_G. Color and quadrant information must be
+supplied as mentioned in the descriptions for escapes 13 and 14.
+
+ The look-up tables are specified to the lower level code by giving
+the end points of the line segments which describe the table function.
+The end points are specified in NDC. This makes for a
+simple, and device independent, upper level code. However, there is no
+obvious (to the writer at least) code to invert the process, and return
+end points for the simplest line segments that would describe a given
+look-up table. (Moreover, there is no mechanism to return such information
+to the upper level.) Therefore, the kernel code is asymmetric, in that
+writes to the tables are fed data in the form of end points, but reads from
+the tables (needed for the kernel implementation of SNAP) return the
+requested number data values as obtained from the hardware.
+
+ The control sequence for the ZOOM function requires, in addition to
+the usual frame/color information, a zoom power followed by the GKI
+coordinates of the pixel to be placed at the screen center. Likewise,
+the SCROLL and SPLIT screen functions require GKI center coordinates.
+
+ The OFFSET and RANGE sequences provide for bias and scaling of the
+image data. Where they take effect is not specified. Offset requires
+a signed number to be added to the referenced data; range is specified
+by a small integer which selects the "range" of the data.
+
+ Control of hardware cursors, trackballs, etc is provided: CURSOR
+can be used to select cursor shape, blink rate, etc. Devices such as
+(trackball) buttons are interrogated as if they are cursors, with a
+cursor number that is greater than to IDS_CSPECIAL. The "key" value
+returned by a "read" call to devices such as the trackball buttons will
+be zero if no button was pressed or some positive number to represent
+the activated device. Any "read" may be instructed to return
+immediately (IDS_READ) or wait for some action (IDS_READ_WT); for
+buttons, there are special IDS_BUT_RD/IDS_BUT_WT.
+
+ Cursors are read and written through the standard GIO interface.
+The cursor number ranges from 1 up through IDS_CSPECIAL-1. Each
+frame has a set of set of cursors associated with it: frame n has
+cursors numbered n, IDS_CSET+n, 2*IDS_CSET+n, etc. Currently,
+IDS_CSPECIAL is 4097, and IDS_CSET is 128, so there can be 128
+different frames, each with 32 cursors. The coordinates associated
+with a given cursor, and hence frame, are NDC for the pixel on which
+the cursor is positioned. If a frame is not being displayed, a cursor
+read for that frame will return NDC for the pixel that would appear at
+the current cursor position if the frame were enabled. Note that the
+NDC used in the cursor_set and cursor_read calls are relative to
+the image planes in the display device; the fact the image data may
+have come from a much larger user "world" is not, and can not be,
+of any concern to the kernel code.
+
+ Cursor 0 is special, and is not associated with a particular frame;
+rather, the kernel is allowed to choose which frame to associate with
+each cursor zero read or write. The IIS code picks the lowest numbered
+frame that is on (being displayed). With split screen activated, a
+frame can be "on" and not be seen; for cursor zero, what matters is
+whether the frame video is active, not whether the split position
+happens to be hiding the frame. The "key" value returned by the cursor
+read routine is the frame number selected by the kernel. Cursor
+IDS_CSPECIAL is also unusual, since it refers to the screen coordinates
+and returns NDC for the screen. It is referred in the code as IDS_CRAW
+(a "raw" cursor) and is needed for positioning the cursor at specific
+points of the screen.
+
+ The MATCH function requires that the frame and color information
+of the control escape sequence point to the reference table; the
+tables to be changed are given in the "data" part with the (IDS_EOD
+terminated) frame sequence preceding the color information. The RW
+field specifies which type of look-up table is to be changed.
+.sp
+.nh
+Interface Routines
+
+ The routines listed here are those used to implement the video
+control package, and are found in the file "cvutil.x".
+Arguments relating to image frames, image colors, display quadrants,
+offset, range, and look-up table data are short integer arrays,
+terminated by IDS_EOD. Cursor position (x and y) are NDC (hence, real).
+All other arguments are integers.
+
+.ls cvclearg (frame, color)
+Clears (erases) the given color (or colors) in the graphics frame given
+by the argument "frame". For the IIS display, the "frame" argument
+is not relevant, there being only one set of graphics frames.
+.le
+.ls cvcleari (frames)
+Clears (erases) all bits in the given image display frames.
+.le
+.ls cv_rdbut
+Reads the buttons on whatever device the kernel code associates with
+this call, and returns an integer representing the button most recently
+pressed. If none pressed, returns zero.
+.le
+.ls cv_wtbut
+Same as cv_rdbut, but if no button pressed, waits until one is. This
+routine will, therefore, always return a non-zero (positive) integer.
+.le
+.ls cv_rcur (cnum, x, y)
+Reads the cursor "cnum" returning the NDC coordinates in x and y. The
+mapping of cursor number to frame is described in the preceding
+section: for cursors with numbers below IDS_CSET (128), the cursor
+refers to the frame (cnum equal 5 means frame 5).
+.le
+.ls cv_scur (cnum, x, y)
+Sets the cursor to the NDC given by x and y for the frame referenced by
+cnum.
+.le
+.ls cv_scraw (x, y)
+Sets the "raw cursor" to position (x,y).
+.le
+.ls cv_rcraw (x, y)
+Reads the "raw cursor" position in (screen) NDC.
+.le
+.ls cvcur (cmd)
+Turns the cursor on (cmd is IDS_ON) or off (IDS_OFF).
+.le
+.ls cvdisplay (instruction, device, frame, color, quad)
+Turns on ("instruction" equals IDS_ON) image plane ("device" equals
+IDS_DISPLAY_I) frame (or frames) in specified colors and quadrants.
+Turn them off if "instruction" equals IDS_OFF. Manipulates graphics
+planes instead if "device" equals IDS_DISPLAY_G.
+.le
+.ls cvmatch (type, refframe, refcolor, frames, color)
+Copies the reference frame and reference color into the given frames
+and color. For the IIS, "type" is either IDS_FRAME_LUT, referring to the
+look-up tables associated with each frame, or IDS_OUTPUT_LUT, referring
+to the global Output Function Memory tables.
+.le
+.ls cvoffset (color, data)
+Sets the offset constants for the specified colors to values given in
+"data"; if there are more colors given than corresponding data items,
+the kernel will reuse the last data item as often as necessary.
+.le
+.ls cvpan (frames, x, y)
+Moves the given frames so that the NDC position (x,y) is at the center
+of the display.
+.le
+.ls cvrange (color, range)
+Scales the output for the given colors; if there are more colors given
+than corresponding range items, the kernel will reuse the last data item
+as often as necessary. Range is a small number which specifies which
+range the data is to be "put" in. For the IIS, there are only 4 useful
+values (1,2,4, and 8); the kernel will map the requested value to the
+next smallest legitimate one.
+.le
+.ls cvreset (code)
+Resets the part of the display referenced by "code". For the IIS, a code
+of IDS_R_HARD refers to (erasing) the image and graphics planes, IDS_R_MEDIUM
+resets the various look-up tables, and IDS_R_SOFT resets the various registers
+(such as zoom, scroll, range, split screen, and so forth).
+.le
+.ls cvsnap (filename, snap_color)
+Creates an IRAF image file, named "filename", which represents the image
+display video output for the specified color (IDS_SNAP_RED, IDS_SNAP_MONO,
+etc). "filename" is a "char" array. The image is of the full display,
+though, since the data is obtained from the kernel line by line via
+get_cellarray calls, partial snapshots can be implemented easily.
+.le
+.ls cvsplit (x,y)
+Sets the split screen point at NDC position (x,y).
+.le
+.ls cvtext (x, y, text, size)
+Writes the given text at NDC position (x,y) in the specified size.
+Currently, font and text direction are set to NORMAL.
+.le
+.ls cvwhich (frame)
+Tells which frames are on. In the current implementation, this relies
+on reading cursor 0: in this special case, the cursor variable passed
+to ggcur() is changed by the kernel to reflect which frame it selected
+(or ERR if no frame is active).
+.le
+.ls cvwlut (device, frames, color, data, n)
+Writes the look-up tables associated with "frames" and "color". "device"
+is IDS_FRAME_LUT or IDS_OUTPUT_LUT. The data to be written is given as
+a series of line segments, and hence is described as a series of GKI
+(x,y) pairs representing the line end points. For connected lines,
+the first pair gives the first line segment starting coordinates, and all
+following pairs the endpoints. The variable "n" gives the number of
+values in "data"; there is no terminating IDS_EOD.
+.le
+.ls cvzoom (frames, power, x, y)
+Zooms, to the given power, the specified frames with each frame
+centered, after the zoom, at the given NDC position.
+.le
+
+ The following two support routines are included in the interface
+package.
+.ls cv_move (in, out)
+Copies the short array "in" into the short array "out", up to and
+including a trailing IDS_EOD. This procedure returns the number of
+items copied.
+.le
+.ls cv_iset (frames)
+Implements the image display escape sequence, with the bitplane
+argument to that escape sequence set to "all".
+.le
+.ls cv_gset (colors)
+Implements the graphics display escape sequence, with the image
+argument to that escape sequence set to "all".
+.le
+.sp
+.nh
+Example
+
+ The following code is used to pan (scroll) the image in response
+to a changing cursor position. It is assumed that the "frame" array
+consists of a list of frames to be panned together, terminated, as
+is almost everything in this code, by IDS_EOD.
+.nf
+
+# Pan subroutine
+
+procedure pansub (frames)
+
+short frames[ARB] # frames to pan
+
+int button
+int cnum, cv_rdbut()
+real x,y, xc, yc
+real oldx, oldy
+
+begin
+ button = cv_rdbut() # clear buttons by reading them
+ call eprintf ("Press any button when done\n")
+
+ # Where is cursor now?
+ # cv_rcraw uses the "RAW CURSOR" which reads and writes in
+ # screen (NDC) coordinates instead of image NDC.
+
+ call cv_rcraw (xc,yc)
+
+ # Pixel to NDC transformation is discussed in the file
+ # "Note.pixel"
+
+ x = x_screen_center_in_NDC
+ y = y_screen_center_in_NDC
+
+ call cv_scraw (x, y) # put cursor at screen center
+
+ # Select a cursor---at least one per frame (conceptually at least)
+
+ cnum = frames[1]
+
+ # If cnum == IDS_EOD, the calling code did not select a frame. So,
+ # if cnum is 0, the kernel will select an active frame as the
+ # one to use when mapping NDC cursor positions to screen
+ # coordinates.
+
+ if (cnum == IDS_EOD)
+ cnum = 0
+
+ # Determine NDC at screen center (where cursor was moved to)
+ # for frame of interest
+ call cv_rcur (cnum, x, y)
+
+ # Restore cursor to original position
+ call cv_scraw (xc, yc)
+
+ repeat {
+ oldx = xc
+ oldy = yc
+ repeat {
+ call cv_rcraw (xc, yc)
+ button = cv_rdbut()
+ } until ( (xc != oldx) || (yc != oldy) || (button > 0))
+ # Determine change and reflect it about current screen
+ # center so image moves in direction cursor moves.
+ x = x - (xc - oldx)
+ y = y - (yc - oldy)
+ # If x or y are <0 or > 1.0, add or subtract 1.0
+ "adjust x,y"
+ call cvpan (frames, x, y)
+ } until (button > 0)
+end
+.fi
+ [The call to cvpan may in fact need to be a series of calls, with
+the array "frames" specifying one frame at a time, and (x,y) being the
+new cursor position for that particular frame, so that differently panned
+frames retain their relative offsets.]
+ The cursor and button routines are given here.
+.nf
+
+# CV_RDBUT -- read button on trackball (or whatever)
+# if none pressed, will get zero back
+
+int procedure cv_rdbut()
+
+int oldcnum
+real x, y
+int button
+int gstati
+
+include "cv.com"
+
+begin
+ oldcnum = gstati (cv_gp, G_CURSOR)
+ call gseti (cv_gp, G_CURSOR, IDS_BUT_RD)
+ call ggcur (cv_gp, x, y, button)
+ call gseti (cv_gp, G_CURSOR, oldcnum)
+ return(button)
+end
+
+# CV_RCUR -- read cursor. The cursor read/set routines do not restore
+# the cursor number...this to avoid numerous stati/seti calls that
+# usually are not needed.
+
+procedure cv_rcur (cnum, x, y)
+
+int cnum
+real x,y
+int junk
+
+include "cv.com"
+
+begin
+ call gseti (cv_gp, G_CURSOR, cnum)
+ call ggcur (cv_gp, x, y, junk)
+end
+
+# CV_SCUR -- set cursor
+
+procedure cv_scur (cnum, x, y)
+
+int cnum
+real x,y
+
+include "cv.com"
+
+begin
+ call gseti (cv_gp, G_CURSOR, cnum)
+ call gscur (cv_gp, x, y)
+end
+
+# CV_SCRAW -- set raw cursor
+
+procedure cv_scraw (x, y)
+
+real x,y
+
+begin
+ call cv_scur (IDS_CRAW, x, y)
+end
+.fi
+
+ The routine cv_move copies its first argument to the second up through
+the required IDS_EOD termination, returning the number of items copied.
+"cv_stack" is a pointer to a pre-allocated stack area that is used to
+build the data array passed to the GIO escape function.
+
+.nf
+# cvpan -- move the image(s) around
+
+procedure cvpan (frames, x, y)
+
+short frames[ARB]
+real x,y # position in NDC
+int count, cv_move()
+
+include "cv.com"
+
+begin
+ Mems[cv_stack] = IDS_SCROLL # Control Unit
+ Mems[cv_stack+1] = IDS_WRITE # Read/Write
+
+ # Three is the number of data items (two coordinates) plus the
+ # terminating IDS_EOD. In many escape sequences, this number
+ # must be determined from the data rather than known in advance.
+
+ Mems[cv_stack+2] = 3
+
+ # Move the frame data, which is of "unknown" length
+
+ count = cv_move (frames, Mems[cv_stack+3])
+
+ # Color is unimportant here, but the color data must exist. The
+ # simplest solution is to use IDS_EOD by itself.
+
+ Mems[cv_stack+3+count] = IDS_EOD # default to all colors
+ Mems[cv_stack+4+count] = 1 # (unused) offset
+ Mems[cv_stack+5+count] = x * GKI_MAXNDC
+ Mems[cv_stack+6+count] = y * GKI_MAXNDC
+ Mems[cv_stack+7+count] = IDS_EOD # for all frames
+ call gescape (cv_gp, IDS_CONTROL, Mems[cv_stack], count+8)
+end
+.fi
+.endhelp
diff --git a/pkg/images/tv/iis/ids/doc/Note.misc b/pkg/images/tv/iis/ids/doc/Note.misc
new file mode 100644
index 00000000..4b3a22de
--- /dev/null
+++ b/pkg/images/tv/iis/ids/doc/Note.misc
@@ -0,0 +1,8 @@
+To implement a full device save/restore, we need:
+zdev_restore(fd)
+zdev_save(fd)
+zim_save(fd,ipl)
+zgr_save(fd,gpl)
+zim_restore(fd,ipl)
+zgr_restore(fd,gpl)
+...zgr are just entry points into zim_{save,restore}(fd,pl)
diff --git a/pkg/images/tv/iis/ids/doc/Note.pixel b/pkg/images/tv/iis/ids/doc/Note.pixel
new file mode 100644
index 00000000..91c0338f
--- /dev/null
+++ b/pkg/images/tv/iis/ids/doc/Note.pixel
@@ -0,0 +1,106 @@
+ Herein is described how pixel coordinates should be encoded into
+GKI metacode units and how this data is then converted back to pixel numbers
+by the "lower level" code. For concreteness, the discussion is based on
+a 512 x 512 display, where the pixels are numbered from 1 to 512 (one-based)
+or 0 to 511 ( zero based). Only the X axis is discussed, the Y axis
+being treated identically.
+ GKI metacode ranges from 0 through 32767, for a total of 32768
+values. In NDC coordinates, the range is from 0.0 through 1.0.
+These coordinates are show in the diagram following.
+.sp
+.nf
+last GKI coordinate of pixel
+ 63 127 191 255 319 32703 32767(!)
+pixel | | | | | | |
+extent-- |<-->||<-->||<-->||<-->||<-->|| ... |<-->||<--->|
+ | | | | | | |
+the |-----|-----|-----|-----|-----| ... |-----|-----|
+pixels | | | | | | ... | | |
+ |-----|-----|-----|-----|-----| ... |-----|-----|
+num- (1-b) 1 2 3 4 5 511 512
+bers (0-b) 0 1 2 3 4 510 511
+ | | | | | | ... | | |
+GKI 0 64 128 192 256 320 32640 32704 32767(!)
+ | | | | | | ... | | |
+NDC 0.0 1/512 2/512 3/512 4/512 5/512 511/512 1.0
+.fi
+.sp
+ The pixels are not points, but rather, in GKI/NDC space, have
+"physical" extent. In NDC coordinates, the pixel boundaries are
+easily calculated as (left boundary = zero-based pixel number / 512)
+and (right boundary = 1-based pixel number / 512). In GKI coordinates,
+each pixel spans 64 GKI units, with the left boundary given by
+"zero-based pixel number times 64". The right boundary is then the
+left boundary plus 64 and then actually references the next pixel.
+That is, the left boundary is included in the pixel, while the right
+boundary is not.
+(Pixel 0 goes from 0 through 63, pixel one from 64 through 127, etc.)
+This works for all pixels except the last one, which would have a
+right boundary of 32768; in this special case, the right boundary
+is defined to be 32767. As will be seen later on, this should cause
+no difficulties.
+ Explicit reference to a particular pixel should, in GKI
+coordinates, refer to the pixel's left (or for Y, lower) edge. Thus,
+pixel 7 (one-based system) is, in GKI, 6*64 or 384.
+ Cell arrays are denoted by their lower-left and upper-right
+corners, with the understanding that all pixels WITHIN this rectangle
+are to be read/written. Thus, an array that covers (one-based)
+(4,10) to (18, 29) implies that, in X, pixels 4 through 17 are referenced.
+Therefore, the GKI coordinate range is from 3*64 up to 17*64, where
+3*64 is the GKI coordinate for the left edge of pixel 4 and 17*64 is
+the GKI coordinate for the right edge of pixel 17. (Remember, the
+right edge of pixel 512 is 32767, not 32768.)
+ The (real) NDC coordinate that is then passed to the interface code
+is determined by dividing the GKI coordinate by 32767. The interface
+code will, ultimately, multiply by 32767 to give the GKI coordinates
+passed to the lower level.
+ The lower level code translates the GKI coordinate values into
+zero-based pixel numbers by multiplying by 512/32768 ( not 32767).
+The (real) pixel numbers so determined are then truncated, and become
+the ones to scroll to, zoom to, or put the cursor on. Therefore,
+when refering to single pixels for such operations, use the left
+boundary of the pixel as the desired GKI/NDC coordinate.
+ Pixel computation for cell arrays is somewhat more complicated.
+The right boundary of a cell array can be the left boundary for
+an adjacent cell array; if the simple truncation scheme were used, that
+coordinate would be included in both cell array operations, which is not
+acceptable (especially for hard copy devices where the resultant overplotting
+would be, at best, objectionable). This problem gives rise to the following
+algorithm. Left (and lower) positions are rounded up to the next pixel
+boundary if the fractional position is greater than or equal 0.5. Right
+(and upper) positions are rounded down to the next pixel boundary if the
+fractional position is less than 0.5; since a fractional pixel value of 0.0
+is less than 0.5, the right/upper pixel will be decreased even if it is
+already on a boundary. The truncated values are then used as the
+INCLUSIVE range of pixels to read or write. (If the positions lie
+within the same pixel, that pixel becomes the X (or Y) range. If the
+positions are in adjacent pixels, the right pixel operation is
+not done if the left pixel moves into the same pixel as the right one.)
+ With this algorithm, the right edge of the display (NDC=1.0,
+GKI=32767) becomes position 511.98, which is not rounded down as the
+fractional part is >= 0.5, and, which, when truncated, turns into 511
+which is what is desired as the (last) included pixel in the range.
+
+ For zoomed (image) displays, fractional pixel coordinates are
+possible in the sense that, for a zoom of 4, pixels 16.0, 16.25,
+16.50, and 16.75, all refer to the same datum. When setting the cursor,
+the lower level code must distinguish all these cases, which have GKI
+values (from a one-based coordinate system) 960, 976, 992, and 1008.
+The lower level code will return these fractional pixel values when reading
+the cursor, but the integral value is the real reference to the data
+point. However, calls to the getcell and putcell routines should use
+16 (aka 960) or the cell array rounding will interfere with what is
+wanted. This does restrict getcell calls from starting/ending in the middle
+of a zoomed (replicated) pixel, but makes the behavior of getcell
+the same as putcell, which cannot write into the middle of a zoomed pixel.
+
+ In summary, users should reference individual pixels by
+specifying their left (or lower) boundaries in GKI/NDC. For cursor
+reference on zoomed displays, fractional (in the sense outlined above)
+pixels may be referenced. Right (or upper) boundaries are used only
+for cell arrays, and except for the very right-most, are determined by
+the user in an operation similar to that for the left boundaries. GKI
+coordinates that are a little too large (not more than 31 units for a
+512 resolution device) will be rounded/truncated to the desired
+coordinate. For cell array operations only, ones a little too small
+will still address the correct pixel.
diff --git a/pkg/images/tv/iis/ids/doc/file.doc b/pkg/images/tv/iis/ids/doc/file.doc
new file mode 100644
index 00000000..504a8330
--- /dev/null
+++ b/pkg/images/tv/iis/ids/doc/file.doc
@@ -0,0 +1,90 @@
+Some notes on the fio system.
+ Binary files.
+ open the binary file with
+ fio_fd = fopnbf(dev_name, mode, zopn_dev, zard_dev, zawr_dev,
+ zawt_dev, zstt_dev, zcl_dev)
+ where dev_name is a char string, terminated with EOS,
+ mode is READ_ONLY, READ_WRITE, WRITE_ONLY, NEW_FILE, APPEND,
+ TEMP_FILE, NEW_COPY
+ and the z routines are for open, read, write, wait, get status,
+ and close ( see system interface reference manual).
+
+ The fio_fd that is returned is then used in calls to read, write, and flush.
+ They have the form write(fio_fd, buffer, #_of_chars)
+ read (fio_fd, buffer, #_of_chars)
+ flush(fio_fd)
+ seek (fio_fd, loffset)
+ long = note (fio_fd)
+ The output data will be buffered in a buffer of CHAR size as set by
+ a kernel call to zstt(). This can be overridden by
+ fsetl(fio_fd, F_BUFSIZE, buffer_size_in_char)
+ Partially filled buffers can be forced out by "flush".
+ Input data is buffered up before being made available to the
+ user; if an i/o call is needed to fill the buffer and it returns with
+ an inadequate number of data items, then the read returns with fewer
+ than requested itmes.
+ The file system can be made to use an external (local) buffer by
+ fseti(fio_fd, F_BUFPTR, new_buffer)
+ For general image i/o, it is desirable to set the ASYNC parameter to YES
+ fseti(fio_fd, F_ASYNC, YES)
+ If the device has a specific block size, this can be set by
+ fseti(fio_fd, F_BLKSIZE, value);
+ the file system will use this value for checking validity of block offsets
+ in reads and writes. If the value is zero, the device is considered a
+ "streaming" device, and no checks are done.
+
+(from Doug)
+The device block size parameter is set at open time by all call to ZSTT__.
+FIO is permissive and allows one to set almost anything with FSET, but some
+of the parameters are best considered read only. This is documented at the
+parameter level in <fset.h>.
+
+Image displays are NOT streaming devices, they are random access, block
+structured devices. If you wish to defeat block alignment checking then
+ZSTT__ may return a block size of 1 char. Note that not all image displays
+are addressable at the pixel level. Even those that are are may be most
+efficiently accessed using line at a time i/o (block size equals 1 line).
+
+If the block size is set to 1 FIO will still access the device in chunks
+the size of the FIO buffer. The file area is partitioned up into a series
+of "pages" the size of the FIO buffer and FIO will fault these pages in and
+out when doing i/o. The only advantages of a block size of 1 are that the
+FIO buffers may be any size (not much of an advantage), and more significantly,
+AREAD and AWRITE calls may be used to randomly access the device. The latter
+are asynchronous and are not buffered, and are the lowest level of i/o
+provided by FIO.
+
+ The form for the z routines is
+ zopn_dev(dev_name, mode, channel)
+ zard_dev(channel, buffer, length, offset)
+ zawr_dev(channel, buffer, length, offset)
+ zawt_dev(channel, bytes_read/written)
+ zstt_dev(channel, what, lvalue)
+ zcl_dev (channel, status)
+
+ where channel is some number to be used however the z routines want, but
+ in the simplest case and under UNIX, would be the file descriptor of the
+ open file as determined by zopn_dev, or, in case of error, is ERR.
+ length and offset are in BYTES. zstt_dev() will be handled locally.
+
+Bytes, yes, but the file offsets are one-indexed. See the System Interface
+reference manual.
+
+ Each of the z*_dev routines above, with the exception of zstt_dev, will
+ ultimately result in a call to one of the system z routines for binary
+ files: zopnbf, zardbf, zawrbf, zawtbf, zclsbf. These routines take
+ the same arguments as the z*_dev routines, with the exception that
+ unix_fd is to be substituted for channel. "unix_fd" is the actual
+ file descriptor that results from the "real" open of the device by
+ zopnbf. It does not need to be visible above the z*_dev routines.
+
+The FIO z-routines for a device do not necessarily resolve into calls to the
+ZFIOBF driver. It is desirable to structure things this way if we can since
+it reduces the size of the kernel, but if necessary the z-routines can be
+system dependent. Since the IIS is data driven and is interfaced in UNIX
+as a file we were able to use the existing ZFIOBF driver, resulting in a
+very clean interface. New devices should also be interfaced this way if
+possible. For various reasons a data stream interface is almost always
+preferable to a control interface (like Sebok's Peritek driver). I would
+seriously consider adding a layer on a control driven device driver to make
+it appear to be data driven, if the driver itself could not be modified.
diff --git a/pkg/images/tv/iis/ids/doc/iis.doc b/pkg/images/tv/iis/ids/doc/iis.doc
new file mode 100644
index 00000000..450de91a
--- /dev/null
+++ b/pkg/images/tv/iis/ids/doc/iis.doc
@@ -0,0 +1,172 @@
+.TL
+The IIS Image Display
+.AU
+Richard Wolff
+.br
+Central Computer Services
+National Optical Astronomy Observatories
+Tucson, Arizona
+.DA
+.PP
+The International Imaging Systems (IIS) Model 70f is a reasonably
+flexible image display with some more advanced capabilities than the IPPS,
+(and, sad to say, some less advanced ones as well). This note describes
+the hardware so that the user can use the device to best advantage.
+The Model 75, which is in use at CTIO, is more elaborate still, but its
+fundamental properties are the same as the 70f boxes in use at NOAO.
+.PP
+The image display has four image planes (frames, memories), each of which
+can hold a 512 x 512 8 bit image. (The hardware can support 12 such planes,
+but only four are installed in the NOAO units.) These planes are loaded
+directly from the host computer; while there is hardware to support a
+13-bit input/8-bit output mapping during load, this is not currently used
+at NOAO. The frames are numbered 1 through 4 and there is nothing to
+distinguish one from another. More than one image plane may be displayed
+at one time; this may create a rather messy screen image, but, of course,
+the hardware doesn't care.
+.PP
+The image is generated by hardware that
+addresses each pixel in turn, and sends the data at that location to the
+video display. Panning (scrolling/roaming) is accomplished simply by
+starting the address generation somewhere other than at the normal starting
+place.
+Each plane has its own starting address, which just means that each
+plane can be panned independently. In contrast, on the model 70,
+all planes zoom together. Zooming is done by pixel replication:
+The master address generator
+"stutters", duplicating an address 2, 4, or 8 times before moving on to
+the next pixel (and duplicating each line 2, 4, or 8 times--an additional
+complication, but a necessary one, which is of interest only to hardware types).
+The master address is then added to the per-image start address
+and the resulting address streams are used to generate
+the per-image data streams, which are added together to form the final image.
+The net result of this is an image on the screen, with user control of the
+placement of each image plane, and with one overall "magnification" factor.
+.PP
+If more than one image is active, the pixel values for a given screen
+position are \fBadded\fR together. Thus, with four image planes, each of
+which has pixels that can range in value from 0 through 255, the output
+image can have pixel values that range from 0 through 3060. Unfortunately,
+the output hardware can handle only values from 0 through 1023. But,
+fortunately, hardware has been included to allow the use to offset and
+scale the data back to the allowed output range. We will look at that
+in more detail later.
+.PP
+The hardware that determines which frames are to be displayed consists
+of "gates" that enable or disable the frame output to the image screen.
+These "gates" are controlled by various data bits in the hardware.
+Conceptually, given the description in the previous paragraphs, one can
+imagine one bit (on or off) for each image frame, and it is these
+bits that the \fBdi\fR command turns on and off. However, there are
+complications, one of which is the split screen mode. Split screen
+hardware allows the user to specify a point, anywhere on the screen,
+where the screen will be divided into (generally, unequally sized) quadrants.
+The display control bits specify not only which images will be active,
+but in which of the four quadrants they will be active.
+There are four control bits per image plane, and so, any image can
+be displayed in any number of quadrants (including none, which means the
+image is "off").
+.PP
+If one imagines the split screen point in the middle of the screen, then
+four quadrants are visible, number 1 being the upper right, number 4 the bottom
+right, etc. As the split screen point is moved to the upper left, quadrant
+four increases in size and the other three decrease. When the split point
+reaches the top left corner (\fIIRAF\fR coordinate (1,512)), only quadrant
+four is left. Due to a hardware decision, this is the normal, non-split,
+screen configuration, the one you get when you type the \fBs o\fR command.
+It would make more sense to set the non-split position so the screen was
+filled with quadrant one, but the hardware won't allow it. So, be
+warned, if you have a split screen display,
+and then reset the split point to the "unsplit" point,
+what you see will be only what you had displayed in quadrant 4.
+.PP
+The model 70f is a color display, not monochrome, and this adds more
+complexity. What happens is that the data from each enabled image plane
+is replicated and sent to three \fIcolor pipelines\fR,
+one for the \fIred\fR gun of the monitor, one for the \fIgreen\fR,
+and one for the \fIblue\fR. If the pipeline data streams are
+the same, we get a black and white image. If they differ, the
+final screen image is colored. Since there are really three data streams
+leaving each image plane, it should not be surprising that there are
+display control bits for each color, as well as each quadrant, of each
+image. Thus (and finally) there are 12 control bits, three colors in each
+of four quadrants, for each image plane. One can set up a display with
+different images in different quadrants, and each colored differently!
+Of course, the coloration is somewhat primative as the choices are limited
+to red on or off, green on or off, both red and green on (yellow), blue on
+or off, etc. More control comes with look-up tables.
+.PP
+The data from the combined image planes is added together in the pipelines.
+There are offset and range registers for each pipeline which allow you to
+bias and scale the data. Offset allows you to add or subtract a 13 bit
+number (+-4095) and range scales the data by a factor of 1,2,4, or 8.
+These are of interest mostly when more than one image is combined; in this
+case, the resulting stream of data should be adjusted so that it
+has its most interesting data in the range 0 through 1023.
+.PP
+Why 1023? The reason is that after offset and range have taken their
+toll, the data is "passed through" a 10 bit in/10 bit out look-up table.
+Look-up tables are digital functions in which each input datum is used
+as an index into a table and the resultant value that is thus "looked-up"
+replaces the datum in the data stream. The look-up tables here
+are known as the \fIoutput\fR
+tables (or, as IIS would have it, the "Output Function Memories").
+There is one for
+each of the three pipelines, and each accepts an input value of 10 bits,
+which limits the data stream to 0 through 1023,
+If the image data in the three pipelines are the same, and the output
+tables are too, then a black and white image results. If, however, the
+pipelines are identical but the tables are different, a colored image
+results. Since this image is not a true color image,
+but simply results from manipulating the three identical color
+pipelines in differing ways, the result is called a pseudo-color image.
+.PP
+The simplest look-up table is a linear function, whose input values run
+from 0 through 1023 and whose output values do the same. The trouble
+with such a linear output table is that the usual case is a single image
+being displayed, in which case the pipeline data is never more than 255.
+With the unit slope table, the maximum output would be 255, which is
+one-quarter of full intensity. A better table in this case would be one of
+slope 4, so 255 would map to 1023 (maximum output). This is what the
+default is, and above 255 input, all values are mapped to 1023. If,
+however, two images are being displayed, then data values may be larger
+than 255 (at overlap points), and as these all map to 1023, only full white
+results. The range/offset registers may be of use here, or a different
+output table should be used.
+.PP
+The output of the "output" tables is combined with the graphics and cursor
+data and sent to the display screen. The graphics planes are one bit
+deep; there are seven of them, and together with the cursor, they form
+an "image" 8 bits deep. In this sense, the graphics planes are just
+like image data, and in particular, they pan and zoom just as the
+image planes do. Of course, the cursor is different. The graphics
+planes are sent through a look-up table of their own, which determines
+what happens when one graphics plane crosses/overlaps others and/or the
+cursor. The resultant data replaces the pipeline data. The graphics
+data can be added to the pipeline data instead of replacing it, but this
+feature is not available in \fIcv\fR at this time. The cursor is really
+a writable 46x64 bit array; thus, its shape can be changed, a feature
+that may be made available to users. Note that there is no quadrant/split
+screen control for the graphics planes.
+.PP
+The final complication, at least as far as the current software is
+concerned, is that each image plane has its own set of three look-up
+tables, one for each color. Thus, there are 4x3 frame look-up tables
+and three output tables. The image tables affect only the data from
+the associated image plane. It is the output of these tables that
+forms the input to the three color pipelines. Each table is an 8 bit in/9
+bit out table, with the output being treated as a signed number (255 to
+-256). (Combining 12 9 bit numbers (a full model 70f) can produce a 13 bit
+number, which is why the offset hardware accepts 13 bit numbers.) In
+the \fIcv\fR software, only positive numbers are used as output from
+the tables. Typically, the image tables are loaded with linear
+functions of varying slope and intercept.
+.PP
+With the two sets of tables, image and output, it is possible to create
+all sorts of interesting pseudo-color images. One possibility is to
+place the appropriate three mappings in the output tables so as to create
+the color (for instance, red can be used only for pixels with large
+values, blue for low values, green for middling ones). Then the image
+tables can be set to adjust the contrast/stretch of the each image
+individually, producing, one assumes, useful and/or delightful
+pseudo-color images.