
svgalib v0.81

1.  Introduction
2.  Overview of supported SVGA chipsets and modes
3.  Description of svgalib functions additional to VGAlib v1.2
4.  How to use svgalib
5.  Structure of chipset driver modules
6.  Changes
7.  Known bugs
8.  Goals
9.  References



1.  Introduction

This is a low level graphics library for Linux, based on VGAlib 1.2 by
Tommy Frandsen. VGAlib supported a number of standard VGA graphics modes, as
well as Tseng ET4000 high resolution 256-color modes. I added support for my
Cirrus 542x based card, including 15/16/24 bit color modes, and merged in the
Trident code from Toomas Losin's tvgalib. It also provides ET4000
hicolor/truecolor DAC support.

It supports transparent virtual console switching, that is, you can
freely switch consoles to and from text and graphics mode consoles using
alt-[function key].

When the library is first used by a program at run-time, the chipset is
detected and the appropriate driver is used. This means that a graphics
program will work on any card that is supported by svgalib, if the mode it
uses is supported by the chipset driver for that card. The library is
upwardly compatible with VGAlib.

The set of drawing functions provided by svgalib itself is limited
(unchanged from VGAlib); you can however use vga_setpage and graph_mem
(which points to the 64K VGA framebuffer) in a program or graphics library.
A external framebuffer graphics library for 1, 2 and 3 byte-per-pixel modes
is included.

One obvious application of the library is a picture viewer. I have made a
simple GIF/JPEG viewer that also supports hicolor/truecolor; it should be
available as spicXX.tar.z (sunsite.unc.edu, /pub/Linux/apps/graphics).

I have added a simple VGA textmode font restoration utility (restorefont) 
which may help if you suffer from XFree86 textmode font corruption. It can
also be used to change the textmode font. It is in the font/ directory.

If you have an ET4000 card, you are advised to hardcode the DAC type in
config.h. You may also have to replace the ET4000 registers (see section 2).

Directories:
.		svgalib sources and test program
font/		Textmode font utilities
gl/		External framebuffer graphics library sources and demos
support/	DOS-based utilities for dumping VGA registers

Run make in the top-level source directory to install. This will copy
libvga.a and libvgagl.a to /usr/lib; vga.h and vgagl.h are copied to
/usr/include. The binary vgatest is created in the main directory; testgl,
fun and speedtest in gl/.


I welcome any comments, suggestions, bug-reports etc.

Harm Hanemaayer
hhanemaa@cs.ruu.nl


Changes in v0.81:

Restorefont (write option) was broken again due to bug in vga.c; gl/text.c
was missing in v0.8. Added vga_disabledriverreport.


Changes in v0.8:

Fixed major bug in vga_getmodeinfo in vgadrv.c. This may have caused
spic to fail on unsupported SVGA cards in 320x200x256.

vga.c split, and other changes (Hartmut Schirmer). Note that mode numbers
beyond 1024x768x256 have changed. Standard VGA modes 720x350x16 and
720x480x16 added.

Virtual console switching improved (bank/linewidth/displaystart preserved).


2.  Overview of supported SVGA chipsets and modes

Supported chipsets:

	VGA

		320x200x256, and the series of 16-color and tweaked modes
		supported by VGAlib, as well as 720x350 and 720x480.

	Cirrus Logic GD542x

		640x480x256, 800x600x256, 1024x768x256, 640x480x32K, 
		640x480x64K, 800x600x32K, 800x600x64K, 1024x768x32K,
		1024x768x64K, 640x480x16M, 320x200x32K, 320x200x64K,
		320x200x16M. The last mode has a logical scanline width
		of 960 bytes, but the VESA BIOS uses 1024. Also,
		800x600x16M at 50 Hz.
		Some bitblt functions are supported.

	Tseng ET4000

		Derived from VGAlib; not the same register values.
		You are advised to set the type of DAC you have in config.h.
		Make sure the colors are right in hicolor mode; the vgatest
		program should draw a bar from dark to light red.
		The ET4000/W32 has been reported to work as an AT&T DAC
		equipped ET4000.
		If the high resolution modes don't work, you can try
		dumping the registers in DOS using the program in the
		support directory and putting them in et4000.c

		640x480x256, 800x600x256, 1024x768x256,
		640x480x32K, 800x600x32K, 640x480x16M

	Trident TVGA 8900C/9000 (and possibly also 8800CS/8900A/B)

		Derived from tvgalib by Toomas Losin.

		640x480x256, 800x600x256, 1024x768x256 (I and NI)

	Oak Technologies OTI-037/67/77

		Does not work.

		(not) 640x480x256, 800x600x256, 1024x768x256



3.  Additional VGAlib functions

	vga_modeinfo *vga_getmodeinfo( int mode )
		Returns pointer to mode information structure for a mode.
		width			Width of mode in pixels.
		height			Height of mode.
		bytesperpixel		Bytes per pixel (framebuffer-wise).
					This is 1, 2 or 3, and 0 for planar
					VGA modes.
		linewidth		Logical scanline width in bytes.
		colors			2, 16, 256, 32768, 65536 or 16M
		maxlogicalwidth 	Maximum logical scanline width (bytes).
		startaddressrange 	Mask of changeable bits of start
					address (in pixels).
		maxpixels		Maximum number of pixels that will
					fit in a logical screen (depends on
					video memory).
		haveblit		Indicates whether bitblit functions
					are available.
					Bit 0: Bitblit
					Bit 1: Fillblit
					Bit 2: Imageblit

	int vga_getcurrentmode()
		Returns the current mode.

	int vga_getdefaultmode()
		Returns the default graphics mode number from the
		GSVGAMODE environment variable; -1 if undefined. The
		enviroment variable can either be a mode number or a mode
		name.

	int vga_getcurrentchipset()
		Returns the current SVGA chipset.

	void vga_setpage( int page )
		Set 64K SVGA page number.

	unsigned char *graph_mem;
		Pointer to 64K VGA frame buffer window. Can be used by
		graphics library on top of VGAlib.

	void vga_waitretrace();
		Wait for vertical retrace. Use to synchronize animation with
		monitor refresh.

	int vga_claimvideomemory( int m ) {
		Declare the amount of video memory in bytes that is to
		be saved when temporarily switching to textmode. Returns
		nonzero if the amount is not available. Defaults to one
		screen when a mode is set.

	void vga_setchipset( int chipset )
		Force chipset (when chipset detection fails).

	void vga_setchipsetandfeatures( int chipset, int par1, int par2 )
		Force chipset, and optional parameters like the exact
		chipset type and the amount of video memory installed.

	void vga_setlogicalwidth( int l )
		Set the logical scanline width to l bytes. Must be a
		multiple of 8.

	void vga_setdisplaystart( int a )
		Set the display start address to a, where the address is the
		number of pixels offset from the start of video memory. Can
		be used for page-flipping and virtual desktop scrolling.

	void vga_setrgbcolor( int r, int g, int b )
		Set the current color to RGB values r, g, and b, each in
		the range 0-255. Does not make sense in 256-color modes.

	The following functions are only defined if the corresponding flag
	in the haveblit field of the mode info structure is set.

	void vga_bitblt( int srcaddr, int destaddr, int w, int h,
	int pitch )
		Bitblit (copy rectangular area in video memory), addresses
		are offsets into video memory (up to 2M). The pitch is the
		logical width of the screen.

	void vga_fillblt( int destaddr, int w, int h, int pitch, int color )
		Fill a rectangular area in video memory with a single color.

	void vga_imageblt( void *srcaddr, int destaddr, int w, int h, int
	pitch )
		Write a rectangular bitmap from system memory to video
		memory.



4.  How to use svgalib (and vgagl)

The function vga_getdefaultmode() checks the environment variable GSVGAMODE
for a default mode, and returns the corresponding mode number. The
environment string can either be a mode number (compatible with VGAlib
Ghostscript), or a mode name as in (G640x480x2, G640x480x16, G640x480x256,
G640x480x32K, G640x480x64K, G640x480x16M). As an example, to set the default
graphics mode to 640x480, 256 colors, use: export GSVGAMODE=G640x480x256
on the shell command line. If a program needs just a linear SVGA resolution,
only modes where bytesperpixel in the vga_modeinfo structure is greater or
equal to 1 should be accepted (this is 0 for tweaked planar 256-color VGA
modes).

Use vga_setmode(graphicsmode) to set a graphics mode. Use vga_setmode(TEXT) to
restore textmode before program exit.

Programs that use svgalib must include vga.h; if they also use the external
graphics library vgagl, vgagl.h must also be included. Linking must be done
with -lvga (and -lvgagl, if vgagl is used).

Functions in the vgagl library have the prefix "gl_". To initialize vgagl,
the graphics context must be set. Example:

	vga_setmode(G320x200x256);
	gl_setcontextvga(G320x200x256);

In this example, the context is set to the physical screen. The context can
be saved into a variable, e.g.

	GraphicsContext physicalscreen;

	gl_getcontext(&physicalscreen).

To define a virtual screen in system memory, use gl_setcontextvgavirtual:

	gl_setcontextvgavirtual(G320x200x256)

which allocates space for a screen identical to 320x200x256 graphics mode,
and makes this virtual screen the current graphics context.

The virtual screen can now be copied to the physical screen as follows:

	gl_copyscreen(&physicalscreen);



5.  Structure of the chipset drivers

	The registers for each mode are stored like the ET4000 modes in
	VGAlib 1.2, i.e. the extended registers at the end. The following
	functions must be provided in a driver:

	saveregs( unsigned char regs[] )
		Saves the chipset-specific registers in regs, starting at
		array index EXT (after the VGA registers).

	setregs( unsigned char regs[] )
		Sets the chipset-specific registers stored in regs from
		index EXT.

	modeavailable( int mode )
		Returns nonzero if mode is available (should check video
		memory).

	getmodeinfo( vga_modeinfo *modeinfo )
		Fills in chipset specific field of mode information
		structure: maxlogicalwidth, startaddressrange (mask of
		significant bits), and maxpixels (video memory divided by
		the number of bytes per pixel). haveblit indicates whether
		bitblt functions are available.

	setmode( int mode )
		Sets all registers for a mode; returns nonzero if mode not
		available. vga_setregs can be called to set the VGA
		registers.

	unlock()
		Unlocks chipset-specific registers.

	lock()
		Lock (protect) chipset-specific registers. Currently not
		called.

	test()
		Identify chipset; initialize (check memory and type) and
		return nonzero if detected.

	setpage( int page )
		Set 64K page number to be mapped at 0xa0000.

	init( int force, int par1, ... )
		Initialize memory and type; called by test. If force is 1,
		the chiptype or the amount of memory can be forced (this
		is pretty useless).

	The following functions are not required; they provide for things
	like page flipping and hardware scrolling virtual desktops.

	setdisplaystart( int addresss )
		Sets the display start address in video memory.

	setlogicalwidth( int width )
		Sets the logical scanline length in bytes. Usually a
		multiple of 8.

	The function getchipset() in vga.c must call the test routine for
	the chipset. The chipsetfunctionslist must be have a pointer
	to the chipsetfunctions table for the chipset (which is the only
	global symbol in a chipset driver). Also, vga.h contains a magic
	number for each chipset.



6.  Changes

Latest version changes are in section 1.

Changes in v0.7:

Trident textmode restoration and SVGA modes should work now on 1M cards
(thanks to Scott Heavner).

Bug fixes in vgagl.


Changes in v0.6:

Trident driver bug fixed; detection cleaned up. 800x600 and 1024x768 on 1Mb
cards don't work correctly.

Added Cirrus 800x600x16M NI (at 50 Hz), and program to set the Cirrus memory
clock to a higher value (setmlck.c).

Added framebuffer graphics library for one, two and three byte-per-pixel
modes. Documentation improved.

vga_setrgbcolor added.

ET4000 Hicolor fixes (thanks to Savio Lam), and other fixes (Scott Heavner).


Changes in v0.5:

Fixed palette register timing bug (caused occasional corruption of textmode
palette).

Added function that checks the environment variable GSVGAMODE for a 
default mode (vga_getdefaultmode). The environment string can either be a
mode number (compatible with VGAlib Ghostscript), or a mode name as
in (G640x480x2, G640x480x16, G640x480x256, G640x480x32K, G640x480x64K,
G640x480x16M, PROMPT (ignore)).


Changes in v0.4:

restorefont.c as distributed in v0.3 missed a case line in a switch
statement which made it useless.

Each VGA register write in the library was producing silly debugging code
(I forgot to restore the macro definition), making everything significantly
larger than neccessary.

Added vga_getchipset function. vgatest now only lists modes that are
available.

The ET4000 driver has been improved, including Hicolor DAC detection 
(thanks to David Monro and Daniel Jackson).

Cirrus driver:
Fixed 5420/2/4 bug, cleaned up detection, changed the 800x600 timings, and 
added missing modes 1024x768x256/32K/64K, as well as 320x200x15/16/24bit.
Also, there's support for some of the accelerated features of the Cirrus
5426, the driver provides bitblt (move box), fillblt (fill box), and
imageblt (write bitmap from system memory) functions.

Display start address can now be meaningfully changed in 16-color and planar
256 color VGA modes for page-flipping (address is expressed as number of
pixels).

Fixed the vga_flip() functionality; if you press escape during
vga_getch() the console is switched to textmode until another key is
pressed. [note: this has been obsoleted by console switching]
The default amount of video memory saved in SVGA modes is the size
of one screen. If the program uses more (if it uses page-flipping, for
example), you must indicate it with the vga_claimvideomemory function. This
prevents 2048 or 1024K being saved when only a few hundred K is required.

svgalib now waits until the virtual console it is running in becomes active
before setting the first graphics mode.

Implemented transparent virtual console switching (which uses vga_flip).



7.  Bugs

	The console switching doesn't preserve the
	display start address, the bank register, and the logical
	scanline length (this is now fixed), and other registers that
	are used to draw in planar VGA modes.

	Wild console switching can cause the text screen to be corrupted,
	especially when switching between two graphics consoles.

	Textmode restoration problems on (some?) 1M Trident cards; this
	should now be fixed.

	On ET4000, having run XFree86 may cause high resolution modes to
	fail.



8.  Goals

	I think the ability to use a VGA/SVGA graphics resolution in one
	virtual	console, and being able to switch to any other virtual console
	and back makes a fairly useful implementation of graphics modes in
	the Linux console.

	Programs that use svgalib must be setuid root. I don't know how
	desirable it is to have this changed; direct port access cannot
	be done without.

	It is important that textmode is restored properly and reliably; it
	is fairly reliable at the moment, but a combination of wild console
	switching between two consoles running graphics can give problems.
	Wild virtual console switching also sometimes corrupts the contents
	of the textmode screen buffer (not the textmode registers or font);
	this is certainly the case when switching between two graphics
	consoles. I don't know if it's svgalib's fault, or that the kernel
	plays a role in this.



9.  References

	VGAlib v1.2: tsx-11.mit.edu, directory pub/linux/sources/libs:
	vgalib12.tar.Z
	tvgalib-1.0.tar.Z is in the same directory.
	SLS seems to be distributing an ancient version of VGAlib.
	svgalibXX.tgz may be found on sunsite.unc.edu, /pub/Linux/libs,
	spic in apps/graphics.

	zgv v1.2 is a GIF/JPEG viewer with a nice file selector that uses
	VGAlib (svgalib is compatible with vgalib), on tsx-11.mit.edu,
	/pub/linux/[binaries|sources]. I would imagine that there may be
	a version that uses svgalib in the future.

	In the info directory of the SIMTEL MSDOS collection, there is a
	package called vgadoc2 which is a collection of VGA/SVGA register
	information.

	The XFree86 driver sources distributed with the link-kit may be
	helpful.
