//------------------------------------------------------------------- // sisinfo.cpp // // This program reads some SVGA hardware registers and reports // several current display parameters. (It is specific to the // SiS 315 GPU, and is incompatible with other SVGA hardware.) // // programmer: ALLAN CRUSE // date begun: 28 JUL 2003 // completion: 13 OCT 2003 //------------------------------------------------------------------- #include // for printf(), perror() #include // for gethostname() #include // for exit() #include // for iopl() #define TSEQ 0x3C4 #define CRTC 0x3D4 int main( int argc, char **argv ) { if ( iopl( 3 ) ) { perror( "iopl" ); exit(1); } //------------------------------------------ // report the program-name and machine-name //------------------------------------------ char hostname[ 64 ]; gethostname( hostname, 63 ); printf( "\nRunning application \'%s\' ", argv[0] ); printf( "on workstation \'%s\' \n", hostname ); //------------------------------------------------------- // quick check: exit if non-SiS graphics processor found //------------------------------------------------------- outb( 0x05, TSEQ); // Extended Sequencer Register 5 short sr05 = inw( TSEQ ); if ( ( sr05 & 0x7FFF ) != 0x2105 ) { printf( "\nSiS graphics processor not detected\n\n" ); exit(1); } outw( 0x8605, TSEQ ); // unlock SiS Extended Registers //------------------------------------------------------ // get the current screen-width (horizontal resolution) //------------------------------------------------------ outb( 0x0B, TSEQ ); short sr0B = inw( TSEQ ); outb( 0x01, CRTC ); short cr01 = inw( CRTC ); unsigned long screen_width = 0; screen_width |= ( cr01 >> 8 )&0x0FF; // bits 7..0 screen_width |= ( sr0B >> 2 )&0x300; // bits 9..8 screen_width += 1; screen_width *= 8; //----------------------------------------------------- // get the current screen-height (vertical resolution) //----------------------------------------------------- outb( 0x0A, TSEQ ); short sr0A = inw( TSEQ ); outb( 0x07, CRTC ); short cr07 = inw( CRTC ); outb( 0x12, CRTC ); short cr12 = inw( CRTC ); unsigned long screen_height = 0; screen_height |= ( cr12 >> 8 )&0x0FF; // bits 7..0 screen_height |= ( cr07 >> 1 )&0x100; // bit 8 screen_height |= ( cr07 >> 5 )&0x200; // bit 9 screen_height |= ( sr0A << 1 )&0x400; // bit 10 screen_height += 1; //---------------------------------------------- // get the current color-depth (bits-per-pixel) //---------------------------------------------- outb( 0x06, TSEQ ); short sr06 = inw( TSEQ ); unsigned long color_depth = 0; switch( ( sr06 >> 10 )&7 ) { case 0: color_depth = 8; break; case 1: color_depth = 15; break; case 2: color_depth = 16; break; case 4: color_depth = 24; break; } //------------------------------------------ // get the current crt start-address offset //------------------------------------------ outb( 0x0D, CRTC ); short cr0D = inw( CRTC ); outb( 0x0C, CRTC ); short cr0C = inw( CRTC ); outb( 0x0D, TSEQ ); short sr0D = inw( TSEQ ); outb( 0x37, TSEQ ); short sr37 = inw( TSEQ ); // NOTE: invalid on SiS 305 unsigned long crt_start_address = 0; crt_start_address |= ( cr0D >> 8 )&0x000000FF; // bits 7..0 crt_start_address |= ( cr0C >> 0 )&0x0000FF00; // bits 15..8 crt_start_address |= ( sr0D << 8 )&0x00FF0000; // bits 23..16 crt_start_address |= ( sr37 <<16 )&0x03000000; // bits 25..24 crt_start_address *= 4; // TODO: Is this always correct? //----------------------------------------- // get the current crt line-compare offset //----------------------------------------- outb( 0x18, CRTC ); short cr18 = inw( CRTC ); outb( 0x09, CRTC ); short cr09 = inw( CRTC ); outb( 0x0F, TSEQ ); short sr0F = inw( TSEQ ); unsigned long crt_line_compare = 0; crt_line_compare |= ( cr18 >> 8 )&0x00FF; // bits 7..0 crt_line_compare |= ( cr07 >> 4 )&0x0100; // bit 8 crt_line_compare |= ( cr09 >> 5 )&0x02FF; // bit 9 crt_line_compare |= ( sr0F >> 0 )&0x0CFF; // bits 11..10 crt_line_compare += 1; //------------------------------------------ // report screen-resolution and pixel-depth //------------------------------------------ printf( "\nscreen-dimensions: " ); printf( "%d by %d ", screen_width, screen_height ); if ( sr06 & (1<<9) ) printf( "\t %d bits-per-pixel ", color_depth ); else printf( "\t text mode " ); printf( "\n" ); //----------------------------------------- // report current crt start-address offset //----------------------------------------- printf( "\ncrt start-address: %d ", crt_start_address ); printf( "(=0x%08X) ", crt_start_address ); //---------------------------------------- // report current crt line_compare offset //---------------------------------------- printf( "\ncrt line-compare: %d ", crt_line_compare ); printf( "(=0x%08X) ", crt_line_compare ); printf( "\n\n" ); }