/* Header section */ VENDOR vendor_name "string" MODEL adapter_model "string" CLASS class "string" MODE name "string"MEMORY([name], base_addr, length); PORT(port_range[ ,port_range...]);
/* Parameter definitions */ DATA { XDRIVER = "name_of_driver"; VISUAL = "visual_type"; DEPTH = "number_of_planes"; PIXWIDTH = "horizontal_pixel_count"; PIXHEIGHT = "vertical_pixel_count"; [PIXBYTES] = "bytes_per_raster_line";] [VIDSCRIPT] = "/usrlib/vidconf/scripts/script";] [RGBBITS] = "red_green_blue_bits_per_pixel";] [...] = as_defined_per_driver" }
/* Procedure definitions */ PROCEDURE SetGraphics { commands and variables } PROCEDURE SetText { commands and variables }
PROCEDURE driver_defined_procedure { commands and variables }
grafinfo files also contain resolution and depth information for each supported graphics adapter. If your graphics adapter has memory mapped registers or a frame buffer that is visible in PC address space, then this information is stored in the grafinfo file.
grafinfo files must be located in the /usr/lib/grafinfo directory, in a subdirectory whose name matches vendor_name in the file. The file itself is named to match the adapter_model string with a .xgi suffix.
The file is divided into three main sections:
The first field is the name of the graphics adapter class, in uppercase or lowercase letters. The second field is the class description (up to 20 characters) that will be used in the Video Configuration Manager prompts. By convention, three leading spaces precede the CLASS string.
width
xheight
[-colors
] [-refresh_rate
] [-other_characteristics
]
width
and height
colors
refresh_rate
The second field is the mode description (up to 40 characters) that will be used in the Video Configuration Manager prompts. By convention, four leading spaces must precede the MODE string.
Use the grafGetMemInfo(D3nfb) routine to access this information:
grafGetMemInfo(grafinfo, NULL, NULL, NULL, &memory_ptr)
port_range
can be expressed as one of the following:
port
port
startport - endport
startport
to endport
, inclusive.
startport:count
count
ports starting at startport
.
parameter_name = value ;parameter_name can be any string that does not conflict with other parameters or keywords. The following parameters are defined for all graphics drivers. There may also be parameters specific to a given driver which are not documented here.
PseudoColor | TrueColor | DirectColor |
StaticColor | GrayScale | StaticGray |
PseudoColor TrueColor DirectColor StaticColor GrayScale StaticGray
Mode 640x480-16 "640x480 16-color" ... PIXWIDTH =640; PIXHEIGHT =480; ... r0 = 0x0012; int10 (r0,1); /* Put in 640x480 16-color mode */
VIDSCRIPT shell scripts are usually located in the /usr/lib/vidconf/scripts directory. The shell script must have execute permission and should exit with a value of 0 (zero) if it is successful. A non-zero exit status causes the Video Configuration Manager to return to the main screen and does not allow the user to select an adapter mode.
If the VIDSCRIPT script modifies kernel tunable parameters or installs a device driver, the kernel must be relinked. The VIDSCRIPT script should not relink the kernel; instead, the script must create an empty .new_unix file in the /usr/lib/vidconf directory before exiting. This causes the Video Configuration Manager to request that a new kernel be relinked, then it will remove the file.
r0
usually corresponds
to x86 register eax,
r1
is ebx, and so forth.
Commands for procedure section
Command | Purpose |
---|---|
and(variable, value); | bitwise (logical) AND on variable, using the specified value. |
bout(count, indexport, dataport );
|
output block of values to an indexed I/O port.
The first count variables starting from r0
are output by sending an index to indexport
and then sending the variables to dataport .
This is analagous to the following C code:
for (index = 0; index < count; index ++) { out (indexport, index); out(dataport, register[index]); } |
in(variable, port); inw(variable, port); |
read I/O port and store value in variable;
in stores a byte value;
inw stores a doublebyte value. |
int10(variable, count); |
perform an INT10 video BIOS call,
mapping the count variables starting at variable
to the CPU general registers.
The registers are mapped in the following order:
AX, BX, CX, DX,
SI, DI, BP, ES.
|
not(variable); | bitwise (logical) NOT on variable |
or(variable, value); | bitwise OR on variable, using specified value |
out(port, value);
outw(port, value); | output value to I/O port. out outputs a byte word. outw outputs a doublebyte word. |
set(variable1, variable2); | set variable1 equal to variable2 |
shl(variable, value); | logical shift left of value bits on variable |
shr(variable, value); | logical shift right of value bits on variable |
wait(delay); | introduces delay of delay microseconds |
xor(variable, value); | bitwise exclusive OR on variable, using the specified value |
variable = value; | assign value to variable |
Command Purpose ----------------------------------------------------------------------------------- and(variable, value); bitwise (logical) AND on variable, using the specified value. bout(count, indexport, dataport); output block of values to an indexed I/O port. The first count variables starting from r0 are output by sending an index to indexport and then sending the variables to dataport. This is analagous to the following C code: for (index = 0; index < count; index ++) { out (indexport, index); out(dataport, register[index]); } in(variable, port); inw(variable, read I/O port and store value in variable; in port); stores a byte value; inw stores a doublebyte value. int10(variable, count); perform an INT10 video BIOS call, mapping the count variables starting at variable to the CPU general registers. The registers are mapped in the following order: AX, BX, CX, DX, SI, DI, BP, ES. not(variable); bitwise (logical) NOT on variable or(variable, value); bitwise OR on variable, using specified value out(port, value); output value to I/O port. out outputs a byte outw(port, value); word. outw outputs a doublebyte word. set(variable1, variable2); set variable1 equal to variable2 shl(variable, value); logical shift left of value bits on variable shr(variable, value); logical shift right of value bits on variable wait(delay); introduces delay of delay microseconds xor(variable, value); bitwise exclusive OR on variable, using the specified value variable = value; assign value to variableFor examples of the use of these commands, see the existing grafinfo files on your system.
typedef struct _mem { int memBase; int memSize; } memThe routines in server/ddx/nfb/common/ddxLoad.c load and parse the appropriate grafinfo file. The ddxScreenRequest(D4nfb) structure contains a pointer to the grafData structure for that display driver to use. A pointer to the ddxScreenRequest structure is passed into the xxxSetup routine.typedef struct _grafData { mem memory[MAXMEM]; int nummem; int port[MAXPORTS]; int numports; functionList *functions; intList *integers; stringList *strings; } grafData;
VENDOR STB "STB" MODEL HORIZON "Horizon VL" CLASS VGA "" MODE 1024x768-256-70 "1024x768 256 colors 70Hz non interlaced"The STB Horizon comes with a video BIOS implementation. This grafinfo entry uses that video BIOS both to establish the monitor type for the BIOS and to put the hardware into a 1024x768-256 color graphics mode. The vast majority of graphics hardware for Intel machines will come with a video BIOS. If possible, always use the video BIOS to initialize the graphics card. Doing this alleviates one of the most difficult tasks in getting your driver running because you don't have to set up the registers on the card. The video BIOS does it for you.MEMORY(0xA0000,0x10000); PORT(VGA);
DATA { XDRIVER = "gd6_8"; VISUAL = "PseudoColor"; DEPTH = 8; PIXWIDTH = 1024; PIXHEIGHT = 768; WINDOWADDR = 0xC0000; /* address of memory window in horizon */ CURSORADDR = 0xFE000; /* address of cursor data */ CURSORSIZE = 0x02000; }
PROCEDURE SetGraphics { r0 = 0x1207; /* monitor type == 7 */ r1 = 0xa2; /* set monitor type */ int10(r0, 2);
r0 = 0x0060; int10(r0, 1);
out(0x3ce, 0x0b); /* select extension reg i/o port */ in(r63,0x3cf); /* read data */ and(r63,0xfe); /* data = enable single 64K page */ out(0x3cf, r63); /* write i/o port */ }
PROCEDURE SetText { r0 = 0x0003; int10(r0, 1); }