svgalib v1.2.10

0.  Introduction
1.  Installation
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 (see file CHANGES)
7.  Known bugs
8.  Goals
9.  References (location of latest version, apps etc.)



0.  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. There's also an ATI mach32 driver
by Michael Weller.

It supports transparent virtual console switching, that is, you can switch
consoles to and from text and graphics mode consoles using alt-[function
key]. Also, svgalib corrects most of VGAlib's textmode corruption behaviour
by catching SIGSEGV, SIGFPE and SIGILL, and ensuring that a program is running
in the currently visible virtual console before setting a graphics mode.

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) and unoptimized; you can however use vga_setpage and graph_mem
(which points to the 64K VGA framebuffer) in a program or graphics library.
A fast external framebuffer graphics library for linear and banked 1, 2, 3
and 4 bytes per pixel modes is included (it also indirectly supports planar
VGA modes). There's a README in the gl/ directory.

One obvious application of the library is a picture viewer. Several are
available, along with animation viewers. See the references at the end of
this document.

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's in the utils/ directory,
along with a README and some other textmode utilities: restoretextmode (which
saves/restores textmode registers), restorepalette, and the script textmode.
If you run the savetextmode script to save textmode information to /tmp,
you'll be able to restore textmode by running the textmode script.

If you have an ET4000 card, you should read the README in the et4000/
directory. You will probably want to replace the ET4000 registers.

Directories:
demos/		Demo and test programs.
utils/		Textmode/font utilities.
src/		Main library source.
src/mouse/	Source for mouse interface.
src/keyboard/	Source for keyboard interface.
gl/		External framebuffer graphics library sources, and docs.
support/	DOS-based utility for dumping VGA registers.
et4000/		Notes, utilities and sample registers for ET4000.
mach32/		Notes and a utility for the ATI mach32 driver.
jump/		Configuration files for building DLL shared library.
sharedlib/	Shared library image and stubs.

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

The source code is rather a mess, but there's hope. The new XFree86-style
driver interface (used by the Cirrus and S3 drivers) and kernel module
graphics that some are experimenting with should provide some momentum.

Harm Hanemaayer
hhanemaa@cs.ruu.nl



1. Installation

Running 'make install' as root should take care of proper installation.
Shared library stubs and images are included in the distribution. Edit the
Makefile to change installation paths and to select the parts that should be
installed, and edit libvga.config to set the monitor and mouse type.

If things go wrong, make sure that you have properly installed a recent libc 
 (i.e. deleted /usr/lib/libgcc.(s)a), and that ld.so is up to date.

If you have an ET4000 card, read the et4000/README and copy the appropriate
register file to et4000.regs. Remember to set the DAC type.

The default behaviour is the following:

Shared libraries are installed in /lib and /usr/local/lib, header files
in /usr/local/include (any old header files in /usr/include are removed).
In the Slackware distribution the linkable libraries are in /usr/lib, and the
utilities in /usr/bin; these are now removed by make install. Until now
just doing make install with Slackware may have produced duplicate binaries,
but fortunately the newer version in usr/local/* would have taken precedence
in use.

The et4000 registers (et4000.regs) are installed as
/etc/vga/libvga.et4000, but only if this file does not exit yet.
The same goes for the configuration file, libvga.config.

Textmode utilities are installed in /usr/local/bin. These are restorefont,
runx, restorepalette, dumpreg, restoretextmode, textmode, savetextmode,
and fix132x43.

If you change the Makefile to install the static libraries, static libraries
are compiled, and installed in /usr/local/include. Note that you do not need
to do this; the shared library is enough.

If you now run 'make', the demo programs are created in the demos/
directory.

You can remove previously installed files (not the et4000 registers and
config file) with 'make uninstall'.

Note that if you change and recompile the (static) library and install it
(you can use 'make static installstaticlib' for this), programs may
still get linked to the (old) shared library version. Try temporarily
removing the stubs in /usr/local/lib, or specifying libvga.a on the
commandline instead of -lvga.

In 1.28 the makefiles were changed. With minimal effort you can compile it
from a seperate (even read-only) source tree. Just make a copy of Makefile
and Makefile.cfg into a writable dir, and change srcdir (or override from
environment) to the directory where the source code is.

`make static' compiles a static version of svgalib. It is not automatically
installed by default but you can enable that from Makefile.cfg.

Using elf or a.out can as easily be configured in the Makefile.cfg. Be
sure to issue a `make clean' after changing the TARGET_FORMAT setting.

If you specified elf, `make install' would compile the shared libs as they
don't come pre-built.  This is not true for a.out and there is a special
hack in the makefiles for this. As svgalib is distributed there is no
attempt to recompile the a.out-sharedlibs. If you have the required tools-*
installed and if you made patches (or just feel like recompiling) issue a
`make clean' or `make shared' to enforce recompiling of the a.out sharedlibs
(from then on even a make install will update the shared library if sources
changed). Issue `make distclean' after a `make shared' to fall back to the
distribution behaviour.

2.  Overview of supported SVGA chipsets and modes

Supported chipsets:

	VGA and compatibles

		320x200x256, and the series of 16-color and non-standard
		planar 256 color modes supported by VGAlib, as well as
		720x348x2.

	Cirrus Logic GD542x/3x

		All the modes, including 256 color, 32K/64K color,
		16M color (3 bytes per pixel) and 32-bit pixel 16M color
		modes (5434). Some bitblt functions are supported.
		The driver doesn't work with mode dumps, but uses a SVGA
		abstraction with mode timings like the X drivers.

	Tseng ET4000/ET4000W32(i/p)

		Derived from VGAlib; not the same register values.
		ET4000 register values are not compatible; see et4000/README.
		Make sure the colors are right in hicolor mode; the vgatest
		program should draw the same color bars for 256 and hicolor
		modes (the DAC type is defined in et4000.regs or the dynamic
		registers file).
		ET4000/W32 based cards usually have an AT&T or Sierra 
		15025/6 DAC. With recent W32p based cards, you might have
		some luck with the AT&T DAC type.
		If the high resolution modes don't work, you can try
		dumping the registers in DOS using the program in the
		et4000 directory and putting them in a file
		(/etc/vga/libvga.et4000 is parsed at runtime if DYNAMIC
		is defined in config.h).

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

		Reports of ET4000/W32i/p functionality are welcome.

		There may be a problem with the way the hicolor DAC register
		is handled; dumped registers may use one of two timing
		methods, with the value written to the register for a
		particular DAC for a hicolor mode (in vgahico.c) being
		correct for just one of the these methods. As a consequence
		some dumped resolutions may work while others don't.

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

		Derived from tvgalib by Toomas Losin.

		640x480x256, 800x600x256, 1024x768x256 (I and NI)
		Might be useful to add 16-color modes (for those equipped
		with a 512K TVGA9000).

	Oak Technologies OTI-037/67/77/87

		Driver by Christopher Wiles; includes 32K color modes
		for OTI-087. See README.oak.

	ATI Mach32

		The driver by Michael Weller supports all BIOS-defined
		modes and more... It hits the best out of your card.
		Some modes may not have nice default timings but it uses
		the ATI's EEPROM for custom config or allows to specify modes
		in libvga.config. Some problems may occur with quite some
		Third party cards (usually on board) Mach32 based controllers
		as they do not completely conform to the Mach32 data sheets.
		Check out README.mach32 (and README.config). Do send feedback.

	ATI Mach64

		THIS IS A NON-FUNCTIONAL DRIVER. USE AT OWN RISK.
		Support for 640x480x256@60hz is being worked on.  At
		the moment it is only supposed to work with a the
		ATI WINTURBO 2MB VRAM VLB RAMDAC ATI68860. 
		Please see README.mach64 for info.

	ATI SVGA (VGA Wonder and friends)

		This is no real driver. I do not support any new modes.
		However it saves additional card setup and thus allows use
		of the plain VGA modes even when you are using non standard
		text modes. It is possible to enforce use of this driver
		even on Mach32 but not very useful.

	S3

		The driver is not complete, but should work on a number of
		cards/RAMDACs, and 640x480x256 should work on most card. The
		best support is for a 801/805 with AT&T20C490-compatible
		RAMDAC, and S3-864 + SDAC.  All 256/32K/64K/16M works for
		them (within the bounds of video memory & ramdac
		restrictions).

		None of the accelaration function is supported yet.

		The chip level code should work with the 964/868/968, but
		most likely the card they come on would use an unsupported
		ramdac/clock chip.  Support for these chips is slowly being
		added.

		Clocks and Ramdac lines in config file supported.
		The maximum pixel clock (in MHz) of the ramdac can be
		set using a Dacspeed line in config file. A reasonable default
		is assumed if the Dacspeed line is omitted.
		Clocks should be the same as in XFree86. Supported
		ramdac IDs:

		Sierra32K, SC15025, SDAC, GenDAC, ATT20C490, ATT20C498, IBMRGB52x

		Example:
		Clocks 25.175 28.3 40 70 50 75 36 44.9 0 118 77 31.5 110 65 72 93.5
		Ramdac att20c490
		DacSpeed 85

		Also supported, at least in combination with the
		SC15025/26A ramdac, is the ICD 2061A clock chip.
		Since it cannot be autodetected you need to define it
		in the config file using a Clockchip line. As there is
		no way to read the current settings out of the 2061, you
		have the option to specify the frequency used when switching
		back to text mode as second argument in the Clockchip line.
		This is especially required if your text mode is an 132
		column mode, since these modes use a clock from the clock
		chip, while 80 column modes use a fixed clock of 25 MHz.
		The text mode frequency defaults to 40 MHz, if omitted.
		
		Example:
		ClockChip icd2061a 40.0


	ARK Logic ARK1000PV/2000PV

		Full support, limited RAMDAC support. Only ARK1000PV
		tested. Supports Clocks and Ramdac lines in config file.

	ALI2301
		Supports 640x480x256, 800x600x256, 1024x768x256 SVGA modes


3.  Additional VGAlib functions

	For vgagl, see gl/README. The mouse and keyboard interfaces are
	"documented" in their headerfiles. There is no automatic mouse
	pointer support; handle it around mouse_(waitfor)update().

	vga_init()
		Initialize library; detects chipset and gives up supervisor
		rights. Recommended first line of any program that uses
		svgalib; vga_setchipset can be used before it to avoid
		detection.
		Svgalib catches a bunch of signals that usually kill your
		program to restore textmode. If you catch signal's before
		calling vga_init() svgalib will restore textmode and prepare
		for shutdown and then call your handler routine. If you don't
		want this catch the signal AFTER calling vga_init and do not
		daisychain to svgalib's original handler.

		WARNING! svgalib needs two signals for it's own purposes
		(that is managing console switches). To avoid problems it uses
		the otherwise unused signals SIGUSR1 and SIGUSR2. However:
		This means that you cannot use them in your program by ANY
		means. They are setup by vga_init() as everything else is.

	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
		flags			Miscellaneous flags.
					Bit 0: Setreadpage/setwritepage
					       available.
					Bit 1: Mode is interlaced.
					Bit 2: Mode is mode-X like (planar
					       256 colors).
					Bit 3: Dynamically loaded mode.
					Bit 4: Can set to linear addressing.
					Bit 5: Linear addressing enabled.
					Bit 6: The following fields in this
					       information structure are set:

		chiptype		the chiptype that was detected/set.
		memory			memory available on the card in KB
		linewidth_unit		use only a multiple of this value for
					set_logicalwidth or set_displaystart
					to ensure graceful alignment of lines
					onto the vga memory in this mode.
		linear_aperture		ptr to a mmaped secondary linear
					framebuffer (NULL if unavailable)
		aperture_size		size of framebuffer in KB. 0 if
					unavailable.
		set_aperture_page	a function taking an int as parameter
					to select a page in the framebuffer if
					aperture_size<memory.
		extensions		pointer to additional info(contents of
					eeprom for mach32 driver.)

	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
		environment variable can either be a mode number or a mode
		name.

	int vga_getcurrentchipset()
		Returns the current SVGA chipset.

	void vga_setmousesupport( int stat )
		Set mouse support; 0 disabled (default), 1 enabled. If
		enabled, the mouse is set up for screen resolution after a
		mode set. You can use the function to set up the mouse in
		vgamouse.h instead for more flexibility.

	void vga_runinbackground( int stat )
		Enable/disable background running of a graphics program
		(1 = enable). Normally, the program is suspended while
		not in the current virtual console. A program can only
		safely run in the background if it doesn't do any video
		access during this time.

	int vga_oktowrite()
		Indicates whether the program is in the console currently
		visible on the screen, that is, whether it is OK to write
		to video memory (if running in the background has been allowed
		with the function above). Note that this is not entirely
		safe, since a console switch interrupt may occur during a
		video operation. [best to avoid this function]

	int vga_getkey()
		Read a character from the keyboard without waiting; returns
		zero if no key pressed.

	void vga_lockvc()
		Disables virtual console switching for safety. Recommended
		when doing register I/O or low-level device handling. Used
		by mouse functions.

	void vga_unlockvc()
		Re-enables virtual console switching.

	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.

	unsigned char *vga_getgraphmem()
		Returns graph_mem.

	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. Use this if you are using more
		than one screen of video memory.

	void vga_setchipset( int chipset )
		Force chipset (when chipset detection fails).
		vga_setchipset(VGA) can be useful if the chipset specific
		stuff or the SVGA detection stuff gives problems.

	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.
		[Only for debugging.]

	void vga_setlogicalwidth( int l )
		Set the logical scanline width to l bytes. Must be a
		multiple of 8. Only changes the VGA register, drawing
		functions don't take it into account.

	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,
		except for hicolor/truecolor modes, which use a unit of
		1 byte. Can be used for page-flipping and virtual desktop
		scrolling. May not work properly for 16 color modes.

	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.

	void vga_setmodeX()
		Try to enable Mode X-like memory organization (only for
		256 color modes using up to 256K of memory like 320x200x256
		and 640x400x256; 320x240x256 etc. are Mode X-like by default).
		This is not guaranteed to work. A new mode should be defined
		for planar 320x200x256.

	void vga_copytoplanar256( unsigned char *virtual, int pitch,
			int voffset, int vpitch, int w, int h )
		Copy part of linear virtual screen in system memory to Mode
		X video memory. pitch is the logical width of the virtual
		screen; voffset is the address offset into video memory;
		vpitch is the logical scanline length of the screen; (w, h)
		is the size of the area to copy in pixels (width must be
		multiple of 4).

	void vga_copytoplanar16( unsigned char *virtual, int pitch,
			int voffset, int vpitch, int w, int h )
		Similar function for 16 color modes (untested); assumes
		pixels stored in consecutive bytes ranging from 0 to 15 in
		the virtual screen.

	void vga_copytoplane( unsigned char *virtual, int pitch,
			int voffset, int vpitch, int w, int h, int plane )
		Similar to vga_copytoplanar16, but only copies one of the
		four 16-color mode planes (plane should be in the range
		0-15).

	int vga_getpixel( int x, int y )
		Read a pixel value from the screen. Was missing for
		planar modes (vgagl does it for packed-pixel modes).

	int vga_setlinearaddressing()
		Switch to linear addressing mode.
		with less than 16Mb of memory (maps at 14Mb).
		vga_getgraphmem returns address where the linear framebuffer
		is mapped. vga_ drawing functions are not supported;
		vgagl does support it (gl_setcontextvga).
		Returns the size of the mapped framebuffer if succesful (can
		be less than total video memory), -1 if not.

	int vga_ext_set(unsigned what, ...)
		set several extended features. Defined are sofar:

	    vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_SET)
		returns an int with the i-th bit set if i is a valid "what"
		parameter for vga_ext_set.

	    vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL)
		returns an int with the i-th bit set if i is a valid "what"
		parameter for vga_accel.

	    vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_FLAGS)
		returns an int with bitflags. Bits that are set are supported
		in the current mode.

	    vga_ext_set(VGA_EXT_SET, int bitflags)
		set all flags that are set in the int bitflags, do not touch
		any other flags. Returns previous setting of all flags.
		
	    vga_ext_set(VGA_EXT_CLEAR, int bitflags)
		clear all flags that are set in the int bitflags, do not touch
		any other flags. Returns previous setting of all flags.

	    vga_ext_set(VGA_EXT_RESET, int bitflags)
		set all flags to the corresponding bits of bitflags.
		Returns previous setting of all flags.

	    You can set flags, and their settings are remembered if not
	    supported in the current mode. This is to avoid problems when
	    switching VC's. The only flag sofar supported is VGA_CLUT8. Use:

	    vga_ext_set(VGA_EXT_SET, VGA_CLUT8)

	    to make the color lookup table for Mach32 cards with type 2 DAC's
	    8 bit per red, green, blue wide in all (even VGA) 256 color modes.

	    vga_ext_set(VGA_EXT_PAGE_OFFSET, int offset)

	    for all following vga_set*page(n) calls (even those implicitly done
	    by svgalib drawing functions) do vga_set*page(n + offset) instead.
	    This is VERY nice for drawing in an offscreen area. However, it
	    requires the mode being able to use more than one page at all as
	    NOT having called vga_setlinearaddressing().

	    A better approach would be to just use higher y values for all
	    draw operations to have them end up in offscreen regions that
	    may be displayed later (cf. vga_setdisplaystart()).

	    The last recently set value for offset is returned.

	int vga_accel(unsigned operation, ...)
		interface to more complicated blitter functions. Not yet
		implemented or even defined.
	    
	void vga_safety_fork( void (*shutdown_routine(void))
		Calling this at the start of a program results in a better
		chance of textmode being restored in case of a crash.
		However it has to raise the iopl level to 3 to work. This is
		a small security breach as it is inherited to any programs
		you fork of. However, some SVGA card drivers have to use
		iopl(3) anyway.
		If you use it call that function as the very first vga_*
		function. Call it right before vga_init(). Note that
		vga_safety_fork will already enter a graphicsmode. (For font
		and grafix state saving).
		Don't overestimate the use of this function.

	int vga_drawscansegment(unsigned char *colors, int x, int y, int length)
		draw a horizontal line of length pixel (read note below!)
		starting at (x,y). The colors drawn are taken from color[0] ..
		color[length - 1]. Svgalib versions prior to 1.2.10 required x,
		y, length to be multiples of 8. This is no longer true.

		In hicolor/truecolor modes, the length must be given in bytes,
		not pixels.

	int vga_getscansegment(unsigned char *colors, int x, int y, int length)
		the direct opposite of vga_drawscansegment(). The line is not
		drawn but instead the colorvalues are taken from the screen and
		copied into color[0] .. color[length - 1].
		All comment on vga_drawscansegment() apply here as well.

	int vga_waitevent(int which, fd_set *input, fd_set *output,
				fd_set *except, struct timeval *timeout)
		This is the only function allowing you to wait for keyboard
		AND mouse events. It is based on the select() library function,
		so for deep understanding of vga_waitevent() look at select(3)
		as well.

		which can be 0 or `ored' together from VGA_MOUSEEVENT and
		VGA_KEYEVENT.
		If you are interested in waiting for file descriptors having
		input available or being ready for new write data or being
		in an exceptional condition (urgent data arrived on a TCP
		stream) set the corresponding bits in the fd_set structures
		passed (see manpage of select (3)). If you want vga_waitevent
		to return after a timeout value pass a struct timeval with
		the desired value. If you are not interested in the
		corresponding events you may pass NULL for ANY of the pointers.

		If NULL is passed for timeout vga_waitevent() will not time out
		but block until any of the other events occurs.

		If the integer returned is < 0 an error occured. Check errno
		for details. If a value >= 0 is returned it is a bitmask
		constructed using VGA_MOUSEEVENT and VGA_KEYEVENT to show
		which of these events occured.

		If any of these two occured the appropriate update functions
		are already called by vga_waitevent().

		vga_waitevent operates in raw as well as non-raw keyboard
		mode. In the latter case use vga_getch() not vga_getkey()
		to read the newly arrived keys.

		Any of the file related conditions being met will be signalled
		by setting exactly the bits for files that met the conditions
		in the corresponding fd_set structures. If a non-NULL timeout
		is passed the remaining time is written into it on return.
		If it is 0 a timeout occured. (again: cf. select(3))

		Therefore, depending on context, vga_waitkey() may return 0 if
		only special, non svgalib, events occured.

		Example 1:
		If you want to wait for a keypress OR a mouse event use:
		vga_waitevent(VGA_MOUSEEVENT | VGA_KEYEVENT,
						NULL, NULL, NULL, NULL);

		If you want to wait for a keypress OR a mouse event but
		non-blocking use:

		#include <sys/time.h>
		struct timeval timeout;
		timeout.tv_sec = 0;
		timeout.tv_usec = 0;
		vga_waitevent(VGA_MOUSEEVENT | VGA_KEYEVENT,
						NULL, NULL, NULL, &timeout);

		You could do a similar thing by just calling

		mouse_update();
		keyboard_update();

		though. There is no such counterpart for example 1.
		
		Example 3:
		A fairly complex demo is in demos/eventtest.c

	The following functions are only defined if the corresponding flag
	in the haveblit field of the mode info structure is set. They are
	not meant as graphics primitives, but more as an interface to the
	blitter in the Cirrus 5426. Note: the maximum height is 1024 for
	the Cirrus routines. They are available on the Mach32 in all non
	VGA modes. The Mach32 expects the pitch to be a multiple of 8
	PIXELS! The Mach32 works pixel oriented. It can mostly use x and y
	Values from 0..1535 and width and heights from 0..2047. The driver
	tries to move around the base address of the Accelerator to perform
	your operations.

	IMPORTANT! This is the old style accel interface. A new one is
	defined by using vga_accel as document int vga.h. But alas, some
	drivers (Mach32) support only this, oldstyle, and some only define
	the new style interface. This is subject to change.

	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. Height h is in Pixels, Width
		w is in BYTES!

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

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

	The following two are only supported for Mach32 currently:

	void vga_hlinelistblt( int ymin, int n, int *xmin, int *xmax,
			int pitch, int c )
		xmin and xmax are pointers to arrays of n integers.
		There are n horizontal lines drawn, for i in 0..(n-1)
		a horizontal line will be drawn from pixel (xmin[i],ymin+i)
		to (xmax[i],ymin+i) using color c. Pixel (0,0) is considered
		to be at the beginning of vga_memory.
		(compare with vga_setdisplaystart(0))

	void vga_blitwait(void)
		wait for any accelerator operation to finish. Though already
		implemented not yet useful.


4.  How to use svgalib (and vgagl)

Do use vga_init as a first line. This will give up root priviledges right
after initialization, making setuid-root binaries relatively safe.

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 (S)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 bash command line. If a program needs just a linear VGA/SVGA resolution
(as required by vgagl), 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 *before* -lvga, if vgagl is used). You can save binary
space by removing the chipset drivers in config.h if you only use standard VGA
(only for static binaries; better link with the shared library).

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 (only the screen type, not the contents) 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);

Note that with a virtual screen in system memory, it is possible to add
fast X-Window support to a program, using MITSHM to copy the framebuffer
to the screen window.



5.  Structure of the chipset drivers

	The chipset specific registers saving function (saveregs) is only
	used directly to save the textmode registers at initialization.

	The chipset specific registers restoring function (setregs) is only
	used directly to return to textmode, and when setting a VGA mode
	after an SVGA mode.

	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.
		Note: providing extended info and an aperture with size
		>= memory and setting bits 4 and 6 in flags will
		automatically enable linear addressing support. 
		

	setmode( int mode, int previous_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 provide for things like page flipping
	and hardware scrolling virtual desktops.

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

	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. Also driver_names[] in vga.c has to
	contain a name for each driver at the correct position.



6.  Changes

See the file CHANGES.



7.  Bugs (This section might be outdated, dunno - MW)

	Using a 132 column textmode may cause graphics modes to fail. Try
	using something like 80x28.

	The console switching doesn't preserve some registers that may be
	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.

	On ET4000, having run XFree86 may cause high resolution modes to
	fail (this is more XFree86's fault).

	The Trident probing routine in the XFree86 server may cause standard
	VGA modes to fail after exiting X on a Cirrus. Try putting a 'Chipset'
	line in your Xconfig to avoid the Trident probe, or use the link kit
	to build a server without the Trident driver. Saving and restoring
	the textmode registers with savetextmode/textmode (restoretextmode)
	should also work. [Note: svgalib now resets the particular extended
	register, but only if the Cirrus driver is used (i.e. the chipset
	is not forced to VGA)] [This is fixed in XFree86 v2.1]

	Some Paradise VGA cards may not work even in standard VGA modes. Can
	anyone confirm this?

	Piping data into a graphics program has problems. I am not
	sure why. A pity, since zcatting a 5Mb FLC file into flip on a 4Mb
	machine would be fun.

	The tseng3 program doesn't recognize any modes on some ET4000 cards.
	Also ET4000 cards with a Acumos/Cirrus DAC may only work correctly
	in 64K color mode.


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 can hardly
	be done without. Root priviledges can now be given up right after
	initialization. I noticed some unimplemented stuff in the kernel
	header files that may be useful, although doing all register I/O via
	the kernel would incur a significant context-switching overhead. An
	alternative might be to have a pseudo /dev/vga device that yields
	the required permissions when opened, the device being readable by
	programs in group vga.

	It is important that textmode is restored properly and reliably; it
	is fairly reliable at the moment, but fast console switching back
	and forth 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).
	Also if a program crashes it may write into the area where the saved
	textmode registers are stored, causing textmode not be restored
	correctly. It would be a good idea to somehow store this information
	in a 'safe' area (say a kernel buffer). Note that the safety_fork
	thing has the same idea.

	Currently, programs that are in graphics mode are suspended while
	not in the current virtual console. Would it be a good idea to let
	them run in the background, virtualizing framebuffer actions (this
	should not be too hard for linear banked SVGA modes)? It would be
	nice to have, say, a raytracer with a real-time display run in the
	background (although just using a seperate real-time viewing
	program is much more elegant).

	Anyone wanting to rewrite it all in a cleaner way (something with
	loadable kernel modules shouldn't hurt performance with linear
	framebuffer/vgagl type applications) is encouraged.

	Also, if anyone feels really strongly about a low-resource and
	truecolor supporting graphical window environment with cut-and-paste,
	I believe it would be surprisingly little work to come up with a
	simple but very useful client-server system with shmem, the most
	useful applications being fairly trivial to write (e.g. shell
	window,	bitmap viewer).	And many X apps would port trivially.


9.  References

	The latest version of svgalib can be found on sunsite.unc.edu and
	mirrors	as svgalibXXX.tgz in the directory /pub/Linux/libs/graphics.

	The original VGAlib is on tsx-11.mit.edu,
	pub/linux/sources/libs/vgalib12.tar.Z.
	tvgalib-1.0.tar.Z is in the same directory.
	SLS has long been distributing an old version of VGAlib.
	Slackware keeps a fairly up-to-date version of svgalib, but it
	may be installed in different directories from what svgalib likes
	to do by default. The current svgalib install tries to remove most
	of this. It also removes /usr/bin/setmclk and /usr/bin/convfont,
	which is a security risk if setuid-root.
	If you want to recompile the shared library, you will need the
	DLL 'tools' package (found on tsx-11.mit.edu, GCC dir).

	Note: This list is horribly outdated. There are many more
	      svgalib appl. as well as the directories might have changed.

	Viewers (in /pub/Linux/apps/graphics/viewers on sunsite):

	spic		Picture viewer; JPG/PPM/GIF; truecolor; scrolling.
	zgv		Full-featured viewer with nice file selector.
	see-jpeg	Shows picture as it is being built up.
	mpeg-linux      svgalib port of the Berkeley MPEG decoder
			(mpeg_play); it also includes an X binary.
	flip		FLI/FLC player (supports SVGA-resolution).

	Games (in /pub/Linux/games on sunsite):

	bdash		B*lderdash clone with sound.
	sasteroids	Very smooth arcade asteroids game.
	yatzy		Neat mouse controlled dice game.
	vga_cardgames	Collection of graphical card games.
	vga_gamespack	Connect4, othello and mines.
	wt		Free state-of-the-art Doom-like engine.
	Maelstrom	A very nice asteroids style game port from Mac.
	Koules		(I've no idea what it looks like)

	Docs

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

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

	Miscellaneous

	There's an alternative RAW-mode keyboard library by Russell Marks for
	use with svgalib on sunsite.

	LIBGRX, the extensive framebuffer library by Csaba Biegl distributed
	with DJGPP, has been ported to Linux. Contact Hartmut Schirmer
	(phc27@rz.uni-kiel.d400.de, subject prefix "HARTMUT:"). A more
	up-to-date port by Daniel Jackson (djackson@icomp.intel.com) is
	on sunsite.

	The vgalib ghostscript device driver sources can be found on
	sunsite, /pub/Linux/apps/graphics.
	Ghostscript patches from Slackware: ftp.cdrom.com, /pub/linux/misc.
	gnuplot patches are on sunsite.

	Mitch D'Souza has written font functions that work in 16 color modes
	and can use VGA textmode (codepage format) fonts; these can be found
	in his g3fax package in sunsite. These functions may go into a later
	version of svgalib.
