home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1999 January
/
pcwk_01_1999.iso
/
Tajnepp
/
MCLK093
/
DETECT.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-15
|
25KB
|
775 lines
// detect.cpp v.093ß 06/15/97
//
// 0.81ß added detection for Vision964/968
// 0.83ß added specific _868/_968 class chipset(s), GD-5434 separate
// if S3+ chipset (Trio/x68/TrioV) detect fails, default to _968
// 0.84ß added detection for GD-5436, distinguish GD-5430/40
// 0.85ß added several more Trident chipsets, thanks to VGADOC4B.ZIP
// I changed order of auto-detection, so TRIDENT is now LAST
// Restored w32p code, however it is NOT autodetected.
// The w32p code is only accessible with the "/F" option
// 0.86ß Fixed corrupted screen bug
// 0.88ß Added S3 Virge and Virge/VX detection
// 0.89ß Added Cirrus Logic GD-5446 detection
// 0.90ß Altered Trio64V+ detection routine, better S3 REV reporting
// 0.92ß Added Aurora64V+, Trio64UV+ (unsupported) detection
// cosmetic changes
// 0.93α Added Tseng Labs ET6000 support (untested)
// Added Cirrus Logic GD-546X support (untested)
// added rudimentary PCI-detection for certain chipsets
// all chipsets detected by detect_pci() include "PCI" f
// in the chipset-identification string (eg. "PCI TGUI9440")
//
// detects ET4000/w32p, ET6000, Trident 9440 & 96XX, Cirrus
// GD-5462 & GD-5464, S3 Trio64V2 & Virge DX/GX
//
// 0.93ß Added stub for Matrox Mystique (1064SG)
//
// detects() installed svga hardware, tries to anyway!
// As of now, I hope it detects Cirrus, S3, and Trident video cards.
// As stated earlier, the W32p code has returned, but autodetection
// routine is inadequate, so to operate W32p-MCLK, you must invoke
// MCLK with "/F" option
#include "vga.h"
#include "s3.h"
#include "cirrus.h"
#include "trident.h"
#include "tseng.h"
#include "matrox.h"
#include "pci.h"
#include<string.h>
#include<dos.h>
#include<stdio.h>
#include<stdlib.h>
/* The following char-tables are used by the detection routine to list
available chipsets in each family. I update the tables as I add
more chipsets. The last entry is always "", which serves as an
endpoint marker...
DO NOT CHANGE THE ORDER OF THE ITEMS WITHIN EACH LIST!!!
*/
const char table_cirrus[][30]={
"GD-5420/22",
"GD-5424/6/8/9",
"GD-5430/40/M30/M40",
"GD-5434",
"GD-5436",
"GD-5446",
"GD-5462",
"GD-5464",
""};
const char table_s3[][30]={
"S3-801/805",
"S3-805i",
"S3-864",
"S3-964", // added v0.86
"S3-732/764 (Trio)",
"S3-765 (Trio64V+)",
"S3-866/868", // cosmetic change v0.93a
"S3-968",
"S3-325 (Virge)", // added v0.88
"S3-988 (Virge/VX)", // added v0.88, not yet tested
"" };
const char table_trident[][30]={
"Trident 9440/96xx",
""
};
const char table_tseng[][30]={
"ET4000/W32p RevA", // cosmetic change v0.93a
"ET4000/W32p RevB+",
"ET6000",
""
};
const char table_matrox[][30]={ // added v0.93b
"1064SG (Mystique)", // coming soon!
// "2064W (Millenium)", // don't know if I can support the Millenium
""
};
// Help menu displays list(s) of either chipsets or families of chipsets.
// if chipset == _AUTO, help-menu returns list of supported families
// otherwise, help-menu returns list of chipsets indicated by chipset
// has two parameters,
message
detect::_help( int family )
{
int i; // loop dummy variable
INITMSG( msg.text );
if ( family == _AUTO ) {
msgout << "(F)orce manual selection of video-chipsets\n\n\t"
<< _argv[ 0 ] << " /F %1\n\t\t(list available devices "
<< "under family%1)"
<< "\n\n\t" << _argv[ 0 ] << " /F %1 %2\n\t\t"
<< "(select device%2 under family%1)\n\n"
<< "Supported families\n------------------\n"
<< "0 Generic VGA\n"
<< (int)_FCIRRUS << " Cirrus Logic\n"
<< (int)_FS3 << " S3, Inc.\n" << (int)_FTSENG
<< " Tseng Labs\n"
<< (int)_FTRIDENT << " Trident Microsystems\n"
<< (int)_FMATROX << " Matrox Graphics, Inc.";
} else
switch ( family ) {
case 0 : msgout << "Generic VGA\n" << "0 VGA";
break;
case _FTSENG : msgout << "Tseng Labs\n";
for ( i = 0; table_tseng[ i ][ 0 ]; ++i )
msgout << i << ' ' << table_tseng[ i ] << '\n' ;
break;
case _FCIRRUS: msgout << "Cirrus Logic\n";
for ( i = 0; table_cirrus[ i ][ 0 ]; ++i )
msgout << i << ' ' << table_cirrus[ i ] << '\n' ;
break;
case _FS3 : msgout << "S3 accelerator\n";
for ( i = 0; table_s3[ i ][ 0 ]; ++i )
msgout << i << ' ' << table_s3[ i ] << '\n' ;
break;
case _FTRIDENT: msgout << "Trident Microsystems\n";
for ( i = 0; table_trident[ i ][ 0 ]; ++i )
msgout << i << ' ' << table_trident[ i ] << '\n' ;
break;
case _FMATROX: msgout << "Matrox Graphics, Inc.\n";
for ( i = 0; table_matrox[ i ][ 0 ]; ++i )
msgout << i << ' ' << table_matrox[ i ] << '\n' ;
break;
default: msgout << family << " = unknown chipset ID";
}
msgout << ends;
return msg;
}
// detect will determine present video-hardware. And initialize a new
// object of type VGA. Returns a pointer to that object.
vga *
detect::_find( int chipset, int family )
{
if ( hardware != NULL ) {
cerr << "\nInitialization error!";
exit (EXIT_FAILURE );
}
strcpy( id.make, "VGA" );
switch ( family ) {
case 0 :
break;
case _FTSENG : hardware = detect_tseng( chipset ); // Force tseng
break;
case _FCIRRUS: hardware = detect_cirrus( chipset ); // force Cirrus
break;
case _FS3 : hardware = detect_s3( chipset ); // force S3
break;
case _FTRIDENT: hardware= detect_trident( chipset ); // force TVGA
break;
default: // Regular auto detection
family = _AUTO;
}
if ( family == _AUTO ) {
hardware = detect_pci(); // Check for PCI based adapters!
if ( hardware == NULL && id.make[ 0 ] == '?' )
hardware = detect_trident();
// Now check for Trident first!
// Reason is that Trident's registers are sensitive to the
// code of later detection routines!
if ( hardware == NULL && id.make[ 0 ] == '?' )
hardware = detect_tseng(); // If not found, _trident()
if ( hardware == NULL && id.make[ 0 ] == '?' )
hardware = detect_s3(); // If not found, _s3()
if ( hardware == NULL && id.make[ 0 ] == '?' )
hardware = detect_cirrus(); // If not found, _trident()
}
if ( !hardware ) // If hardware == NULL ... never set-up...
hardware = new vga( id ); // Setup generic VGA hardware
return hardware;
}
vga * // For debugging purposes only!
detect::_debug( int mode )
{
vga_info temp = { "S3", "Vision968", "??" };
if ( !hardware )
hardware = new _864( temp );
else
exit( EXIT_FAILURE );
return hardware;
}
vga *
detect::detect_cirrus( int mode )
{
// vga *hardware = NULL;
union REGS reg;
hardware->write_SR( 0x06, 0x12 ); // Unlock Cirrus SVGA registers
uchar _CR28 = hardware->read_CR( 0x28 ) ; // ClassID (5430/40)
uchar _CR27 = hardware->read_CR( 0x27 ) ; // Read CL-GD ID register
_CR27 = ( _CR27 >> 2 ) & 0x3F; // 1234 5678 -> 0012 3456
reg.h.ah = 0x12;
reg.h.bl = 0x80; // Inquire VGA type
int86( 0x10, ®, ® );
if ( reg.h.bl != 0x80 )
sprintf( id.revision, "%02X", reg.h.bl );
else
strcpy( id.revision, "??" );
strcpy( id.make, "Cirrus Logic" ); // Let's assume it's a cirrus
if ( mode == _AUTO )
switch ( _CR27 ) {
case 34: strcpy( id.chipset, "GD-5420" );
hardware = new _cirrus( id ); break;
case 35: strcpy( id.chipset, "GD-5422" );
hardware = new _cirrus( id ); break;
case 37: strcpy( id.chipset, "GD-5424" );
hardware = new _GD5424( id ); break;
case 36: strcpy( id.chipset, "GD-5426" );
hardware = new _GD5424( id ); break;
case 38: strcpy( id.chipset, "GD-5428" );
hardware = new _GD5424( id ); break;
case 39: strcpy( id.chipset, "GD-5429" );
hardware = new _GD5424( id ); break;
case 42: strcpy( id.chipset, "GD-5434" );
hardware = new _GD5434( id ); break;
case 41: strcpy( id.chipset, "GD-5432 ??? " );
hardware = new _GD543x( id ); break;
case 43: strcpy( id.chipset, "GD-5436" );
hardware = new _GD5436( id ); break;
case 46: strcpy( id.chipset, "GD-5446" );
hardware = new _GD5436( id ); break;
case 40:
switch( _CR28 ) { // Distinguish 5430/40
case 0xFF: strcpy( id.chipset, "GD-5430" );
break;
case 0x01: strcpy( id.chipset, "GD-54M30" );
break;
case 0x03: strcpy( id.chipset, "GD-5440" );
break;
case 0x07: strcpy( id.chipset, "GD-54M40" );
break;
default: strcpy( id.chipset, "?!?GD-5430/40" );
}
hardware = new _GD543x( id ); break;
default: // Couldn't identify Cirrus chipset
strcpy( id.make, "? (tried Cirrus )" );
strcpy( id.revision, "?" );
sprintf( id.chipset, "? _CR27 = 0x%02X",
hardware->read_CR( 0x27 ) );
if ( mode == _FCIRRUS ) // Forced Cirrus detection
hardware = new _cirrus( id );
} // Else, if user FORCES a video-chipset (manual selection)
else if ( mode != _AUTO ) {
strcpy( id.chipset, table_cirrus[ mode ] );
switch ( mode ) {
case 0: hardware = new _cirrus( id );
break;
case 1: hardware = new _GD5424( id );
break;
case 2: hardware = new _GD543x( id );
break;
case 3: hardware = new _GD5434( id );
break;
case 4: hardware = new _GD5436( id );
break;
case 5: hardware = new _GD5436( id );
break;
case 6: hardware = new _GD5462( id );
break;
case 7: hardware = new _GD5464( id );
break;
default:
cerr << "Unknown Cirrus Logic chipset.";
exit( EXIT_FAILURE );
}
}
return hardware; // Return whatever we found, even if nothing
}
vga *
detect::detect_s3( int mode )
{
// vga *hardware = NULL;
uchar _CR30, _CR2D, _CR2E, _CR2F, nibble, _DAC;
// _CR2E for all newer S3 chips...Trio on up
// _CR2F only needed to detect Trio64V+
hardware->write_CR( 0x38, 0x48 ); // Unlock S3 VGA registers
hardware->write_CR( 0x39, 0xA0 ); // Unlock S3 registers
_CR30= hardware->read_CR( 0x30 ); // Read _CR30 "S3 chip ID"
_CR2D= hardware->read_CR( 0x2D ); // Read _CR2D "S3 secondary ID"
_CR2E= hardware->read_CR( 0x2E ); // Read _CR2E "S3 secondary ID"
_CR2F= hardware->read_CR( 0x2F ); // If 4X, then we've got Trio64V+
nibble = _CR30 & 0xF0; // Mask out revision status (lower 4bits)
strcpy( id.make, "S3" ); // Let's assume it's an S3 chip
sprintf( id.revision, "_CR30(3:0) = %02X", _CR30 & 0x0F );
if ( mode == _AUTO )
switch ( nibble ) {
case 0x80: strcpy( id.chipset, "911/924 not supported" );
break; // Not supported
case 0x90: strcpy ( id.chipset, "928 not supported" );
break; // Not supported
case 0xA0: if ( _CR30 == 0xA8 ) {
strcpy( id.chipset, "805i" );
hardware = new _805i( id ); }
else { strcpy( id.chipset, "801/805" );
hardware = new _S3( id ); }
break;
case 0xB0: strcpy ( id.chipset, "928PCI not supported" );
break; // Not supported
case 0xC0: strcpy( id.chipset, "864" );
hardware = new _864( id ); break;
case 0xD0: strcpy( id.chipset, "964" );
hardware = new _964( id ); break;
case 0xE0: // 0xE0, Trio/x68 or , newer S3chips
sprintf( id.revision,"_CR2F = %02X",hardware->read_CR( 0x2F ) );
// These newer chips have different REV register
switch( _CR2E ) {
case 0x10: strcpy( id.chipset, "732 (Trio32)" );
hardware = new _Trio( id ); break;
case 0x11: // 0.90 changed 64V+ detection code
if ( ( _CR2F >= 0x40 ) && ( _CR2F <= 0x5F ) ) {
strcpy( id.chipset, "765 (Trio64V+)" );
hardware = new _Triov( id );
} else {
strcpy( id.chipset, "764 (Trio64)" );
hardware = new _Trio( id );
}
break;
case 0x12: // 0.92 recognizes Aurora64V+ (UMA)
strcpy( id.chipset, "Aurora64V+ (use Trio64V+)");
hardware = new _Triov( id ); break;
case 0x14: // 0.92 recognizes Trio64UV+ (UMA)
strcpy( id.chipset, "767 (Trio64UV+) not supported");
break; // UMA chipsets not supported
case 0x31: strcpy( id.chipset, "325 (Virge)" );
hardware = new _Virge( id ); break;
case 0x3D: strcpy( id.chipset, "988 (VirgeVX)" );
hardware = new _VirgeVX( id ); break;
case 0x80: strcpy( id.chipset, "866");
hardware = new _868( id ); break;
case 0x90: strcpy( id.chipset, "868");
hardware = new _868( id ); break;
case 0xF0: strcpy( id.chipset, "968");
hardware = new _968( id ); break;
default: sprintf( id.chipset, // UNKNOWN EXT
"Unknown _CR30 = 0x%02X, _CR2D/_CR2E = 0x%02X/%02X",
_CR30, _CR2D, _CR2E );
hardware = new _968( id );
}
break;
default: strcpy( id.make, "? (tried S3) " );
sprintf ( id.chipset, "? _CR30 = 0x%02X, _CR2D/_CR2E = 0x%02X/%02X",
_CR30, _CR2D, _CR2E );
strcpy ( id.revision, "?" );
if ( mode == _FS3 ) // Forced S3 detection
hardware = new _S3( id );
} // else, user-selected S3 chipset
else if ( mode != _AUTO ) {
strcpy( id.chipset, table_s3[ mode ] );
switch ( mode ) {
case 0: hardware = new _S3( id );
break;
case 1: hardware = new _805i( id );
break;
case 2: hardware = new _864( id );
break;
case 3: hardware = new _964( id ); // added v0.86
break;
case 4: hardware = new _Trio( id );
break;
case 5: hardware = new _Triov( id );
break;
case 6: hardware = new _868( id );
break;
case 7: hardware = new _968( id );
break;
case 8: hardware = new _Virge( id );
break;
case 9: hardware = new _VirgeVX( id );
break;
default:
cerr << "Unknown S3 chipset.";
exit( EXIT_FAILURE );
}
}
return hardware; // Return whatever we found, even if nothing
}
vga * // Trident support not implemented
detect::detect_trident( int mode )
{
// vga *hardware = NULL ;
uchar _SR0B = 0, _SR0E; // Trident ID register
uchar old_mode; // Preserve low/high bytes of mode-register
uchar temp;
// INITMSG( id.make );
// msgout << "Trident" << ends ; // Let's assume it's a Trident
strcpy( id.make, "Trident" ); // Let's assume it's a Trident
strcpy( id.revision, "??" );
// INITMSG( id.chipset );
// Following code adapted from VGADOC4B.ZIP
hardware->write_SR( 0x0B, 0 ); //Write $00 to force new-mode
_SR0B = hardware->read_SR( 0x0B ); // this forces old mode
_SR0E = hardware->read_SR( 0x0E );
hardware->write_SR( 0x0E, _SR0E ^ 0x55 ); // xor $55
hardware->write_SR( 0x0E, _SR0E ^ 0x02 ); // xor $02
if ( mode == _AUTO )
switch ( _SR0B ) {
case 1 : case 2 : strcpy( id.chipset, "8800" );
break; // Not supported
case 3: case 4: case 0x13: case 0x12: case 0x33:
strcpy( id.chipset, "8900 series" );
break;
case 0x23: case 0x43: strcpy( id.chipset, "9000 series" );
break; // Not supported
case 0x53: strcpy( id.chipset, "9200CXr" );
break; // Not supported
case 0xC3: case 0x73: strcpy( id.chipset, "GUI9420??" );
break; // Not supported
case 0x93: strcpy( id.chipset, "GUI9400CXi" );
break; // Not supported
case 0xF3: strcpy( id.chipset, "GUI9430??" );
break;
case 0xE3: strcpy( id.chipset, "GUI9440" );
hardware = new _TR9440( id );
break;
case 0xD3: strcpy( id.chipset, "GUI96xx" );
hardware = new _TR9440( id );
break;
case 0x63: case 0x83: case 0xA3:
strcpy( id.chipset, "A Trident LCD chipset" );
break;
default:
sprintf( id.chipset, "? Unknown _SR0B = 0x%02X", _SR0B );
strcpy( id.make, "? (tried Trident)" );
strcpy( id.revision, "?" );
if ( mode == _FTRIDENT ) {
cerr << "\nTRIDENT not supported yet.";
exit( EXIT_FAILURE );
}
}
else if ( mode != _AUTO ) {
strcpy( id.chipset, table_trident[ mode ] );
switch( mode ) {
case 0 : hardware = new _TR9440( id );
break;
default:
cerr << "Unknown Trident chipset.";
exit( EXIT_FAILURE );
}
}
//}
return hardware; // Return whatever we found, even if nothing
}
// v0.93...added ET6000 PCI/VL detection
vga *
detect::detect_tseng( int mode )
{
// vga *hardware = NULL ;
dword creg;
int i;
outportb( 0x3BF, 0x03 ); // Unlock W32P "key"
outportb( 0x3D8, 0xA0 ); // Unlock W32P "key"
for ( i = 0; i < 4; ++ i )
outportb( 0xF100 + i, 0 ); // Activate VLbus-IO for ET6000
strcpy( id.make, "? (tried Tseng Labs)" );
strcpy( id.chipset, "?" );
strcpy( id.revision, "?" );
if ( mode == _AUTO ) {
creg.b.b0 = inportb( 0xF100 );
creg.b.b1 = inportb( 0xF101 );
creg.b.b2 = inportb( 0xF102 );
creg.b.b3 = inportb( 0xF103 );
// Test for Tesng Labs ET6000, vendor 0x100C, Device 0x3208
if ( creg.w.w0 == 0x100C && creg.w.w1 == 0x3208 )
{
sprintf( id.make, "Tseng Labs" );
sprintf( id.chipset, "ET6000VL" );
sprintf( id.revision, "%02X", inportb( 0xF100 + 8 ) );
hardware = new _et6000( id );
}
}
else if ( mode != _AUTO ) {
strcpy( id.chipset, table_tseng[ mode ] );
switch( mode ) {
case 0 : hardware = new _w32p( id );
break;
case 1 : hardware = new _w32pb( id );
break;
case 2 : hardware = new _et6000( id );
break;
default:
cerr << "Unknown Tseng Labs chipset.";
exit( EXIT_FAILURE );
}
}
return hardware;
}
// Added PCI-detection for certain chipsets
vga *
detect::detect_pci( int mode )
{
// pci_bios_type *pci_bios;
// pci_device_handle_type pci_vga;
uchar rev; // Revision ID
dword creg; // Configuration test variable to test for VL-bus ET6000
pci_bios=new pci_bios_type; // Open PCI-bios routines, INT 0x1A
// Note, the absence of BIOS-support for PCI does not automatically
// mean the host-bus isn't PCI. It could mean an older system BIOS.
// Currently, MCLK requires BIOS-support for PCI-devices.
if ( pci_bios->installation_check() == NULL )
return NULL; // No PCI BIOS, no PCI-devices found!
pci_vga.vendor=0x100C; // Tseng Labs, Inc.
pci_vga.device=0x3208; // ET-6000
pci_vga.index = 0; // Only look for 1st installed ET6000
// Look for PCI ET6000, if found, find_device() will store
// the host/bus# and dev/func# into our *pci_vga object
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI ET6000" );
sprintf( id.make, "Tseng Labs" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _et6000( id );
return hardware;
}
pci_vga.vendor=0x100C; // Tseng Labs, Inc.
pci_vga.device=0x3202; // ET-4000/W32P
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI ET4000/W32P RevA" );
sprintf( id.make, "Tseng Labs" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _w32p( id );
return hardware;
}
pci_vga.vendor=0x100C; // Tseng Labs, Inc.
pci_vga.device=0x3206; // ET-4000/W32P
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI ET4000/W32P" );
sprintf( id.make, "Tseng Labs" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _w32pb( id );
return hardware;
}
pci_vga.vendor=0x100C; // Tseng Labs, Inc.
pci_vga.device=0x3207; // ET-4000/W32P
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI ET4000/W32P" );
sprintf( id.make, "Tseng Labs" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _w32pb( id );
return hardware;
}
pci_vga.vendor=0x1013; // Cirrus Logic, Inc.
pci_vga.device=0xD0; // Laguna GD-5462
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "Cirrus Logic" );
sprintf( id.make, "PCI GD-5462" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _GD5462( id );
return hardware;
}
pci_vga.vendor=0x1013; // Cirrus Logic, Inc.
pci_vga.device=0xD4; // Laguna GD-5464
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "Cirrus Logic" );
sprintf( id.make, "PCI GD-5464" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _GD5464( id );
return hardware;
}
pci_vga.vendor=0x1023; // Trident Microsystems, Inc.
pci_vga.device=0x9440; // TGUI 9440
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI TGUI9440" );
sprintf( id.make, "Trident Microsystems" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _TR9440( id );
return hardware;
}
pci_vga.vendor=0x1023; // Trident Microsystems, Inc.
pci_vga.device=0x9660; // TGUI 96XX
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI TGUI96xx" );
sprintf( id.make, "Trident Microsystems" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _TR9440( id );
return hardware;
}
pci_vga.vendor=0x5333; // S3, Inc.
pci_vga.device=0x8A01; // Virge DX/GX
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI Virge DX/GX" );
sprintf( id.make, "S3" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _Virge( id );
return hardware;
}
pci_vga.vendor=0x5333; // S3, Inc.
pci_vga.device=0x8901; // Trio64V2
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI Trio64V2 (775)" );
sprintf( id.make, "S3" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _Triov( id );
return hardware;
}
pci_vga.vendor=0x5333; // S3, Inc.
pci_vga.device=0x5631; // Virge (325)
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI Virge (325)" );
sprintf( id.make, "S3" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _Virge( id );
return hardware;
}
pci_vga.vendor=0x5333; // S3, Inc.
pci_vga.device=0x883D; // Virge/VX
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI Virge/VX (988)" );
sprintf( id.make, "S3" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _VirgeVX( id );
return hardware;
}
pci_vga.vendor=0x102B; // Matrox Graphics, Inc.
pci_vga.device=0x051A; // Matrox Mystique (1064SG)
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI Mystique (1064SG)" );
sprintf( id.make, "Matrox" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = new _Mystique( id );
return hardware;
}
pci_vga.vendor=0x102B; // Matrox Graphics, Inc.
pci_vga.device=0x0519; // Matrox MGA Storm (2064W)
pci_vga.index = 0; // Only look for 1st installed device
if ( pci_bios->find_device( &pci_vga ) == TRUE )
{
sprintf( id.chipset, "PCI Millenium (2064W)" );
sprintf( id.make, "Matrox" );
pci_bios->read_cbyte( pci_vga, 0x8, &rev );
sprintf( id.revision, "%02X", rev );
hardware = NULL; // Support coming soon!
return hardware;
}
sprintf( id.make, "?" ); // Didn't find anything
return hardware;
}