home *** CD-ROM | disk | FTP | other *** search
- /* cirrus.cpp 03/21/97 0.93α
- *
- * Includes class definitions for Cirrus Logic
- * GD-5420/22 (_cirrus) 1 setting, tested
- * GD-5424 and up ( 3 settings, tested...4th setting is read-back only)
- * GD-543x ( 3 settings, only the 1st one is tested )
- *
- * v0.83B, GD-5434 MCLK will warn user about GD-5434 BIOS
- * v0.83B, tries to get Cirrus Silicon revision (through BIOS 0x10)
- * v0.84B, Cirrus Logic GD-5436 specific code
- * (GD5430/5440 grouped together)
- * v0.85B, converted sprintf calls to ostrstream << method
- * v0.89B, modified 5436 functions to read "5436/46"
- * v0.92B, cosmetic changes (no new code)
- * v0.93α, added Cirrus Logic GD-546X code (untested), more cosmetic changes
- */
-
-
- #include "cirrus.h"
-
- #include<dos.h>
- #include<string.h>
- #include<stdio.h>
- #include<stdlib.h>
- #include<iostreams.h>
-
- /*
- * cirrus.h
- * cirrus class function definitions
- */
-
-
- message
- _cirrus::_info( void )
- {
- INITMSG( msg.text );
- union REGS reg;
- reg.h.ah = 0x12 ;
- reg.h.bl = 0x80 ;
- int86( 0x10, ®, ® );
-
- if ( reg.h.bl != 0x80 ) {
- msgout << "Chip revision = " ;
- hexout( msgout, reg.h.bl ); // print reg.h.bl in "XX" format
- } else
- msgout << "Chip revision NOT available.";
-
- msgout << " RAS timing mode = ";
- if ( read_bit( _SRindex, 0x0F, 2 ) )
- msgout << "standard (faster) ";
- else
- msgout << "extended (slower) ";
-
- msgout << ends ;
- return msg;
- }
-
-
- void
- _cirrus::_mclk( int cmd )
- {
- uchar _SR1F = read_SR ( 0x1F ) & 0x3F; // Read _SR1F register
- uchar new_MCLK = _SR1F; // New MCLK byte
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "0 GD-54xx MCLK memory clock setting\n" << ends;
- return;
- }
-
- // sprintf( msg.text, "Current MCLK = %.2fMHz (%02dd)", get_mclkfreq(),
- // _SR1F );
- msgout.precision( 2 );
- msgout << "Old MCLK = " << get_mclkfreq() << "MHz (" << (int)(_SR1F)
- << "d)";
-
- if ( param[ 0 ] != NULL ) // Only the 1st parameter is used
- new_MCLK = ( (uchar) atoi( param[ 0 ] ) ) & 0x3F;
-
- switch ( cmd ) {
- case _SET : _SR1F = read_SR( 0x1F) & 0xC0; // XX00 0000
- // Now perform a READ/MODIFY/WRITE to _SR1F
- write_SR( 0x1F, _SR1F | new_MCLK );
- msgout << "\nNew MCLK = " << get_mclkfreq() << "MHz ("
- << (int)( new_MCLK ) << "d)";
- // sprintf( msg.temp, "\nNew MCLK = %.2fMHz (%02dd) ",
- // get_mclkfreq(), new_MCLK );
- // strcat( msg.text, msg.temp );
- break;
- case _GET : case _HELP: msgout
- << "\nNote: GD-5429 max = 60MHz, all other GD=542x = 50MHz"
- << "\n GD-5430/5440 max = 60MHz, GD-5436 = 80MHz"
- << "\n\tInput = 0-63dec, example values : "
- << "\n\t23d = 41.17MHz\n\t25d = 44.74MHz"
- << "\n\t28d = 50.11MHz\n\tOther values ok.";
- break;
- default:
- msgout << "cirrus::_mclk(cmd) UNRECOGNIZED cmd.";
- status = EXIT_FAILURE;
- }
- msgout << ends;
- }
-
-
- void
- _GD5424::_fxn2( int cmd ) // RDY delay for I/O (local bus only)
- {
- INITMSG( msg.text );
- if ( cmd == _QUERY ) {
- msgout << "2 GD-5424/6/8/9 RDY delay for I/O (local-bus only)\n"
- << ends;
- return;
- }
-
-
- uchar _SR16 = ( read_SR( 0x16 ) >> 6 ) & 0x03; // Read _SR16 register
- uchar new_RDY= 0x03; // Default to 2T delay
-
- if ( param[ 0 ] != NULL )
- new_RDY = (uchar)atoi( param[ 0 ] );
-
- // sprintf( msg.text, "Old I/O RDY delay = %uT (%ud) ", _SR16 / 2, _SR16 );
- msgout << "Old I/O RDY delay = " << (int) (_SR16 / 2) << "T ("
- << (int)_SR16 << ") ";
-
- switch ( cmd ) {
- case _SET: _SR16 = read_SR( 0x16 ) & 0x3F; // DD00 0000
- write_SR( 0x16, ( ( new_RDY << 6 ) & 0xC0 ) | _SR16 );
- // sprintf( msg.temp, "\nNew delay = %uT (%ud) ",
- // new_RDY /2 , new_RDY );
- // strcat ( msg.text, msg.temp );
- msgout << "\nNew delay = " << (int) (new_RDY / 2) << "T ("
- << (int)new_RDY << ") ";
- break;
- case _GET: case _HELP:
- msgout << "\n(local-bus only)\nActual clock delays (T) / XXd"
- << " (where XXd is INPUT value in decimal.)"
- << "\n\t0T/00\n\t0T/01\n\t1T/02\n\t1T/03";
- break;
- default:
- msgout << "_GD5424::_fxn2(cmd) UNRECOGNIZED cmd.";
- status = EXIT_FAILURE;
- }
- msgout << ends;
- }
-
- /* REMOVED, BECAUSE CIRRUS BIOS RE-PROGRAMS FIFO THRESHOLD FOR EVERY mode!
- void
- _GD5424::_fxn4( int cmd ) // FIFO refilling threshold (_SR16 bits 3-0)
- {
- if ( cmd == _QUERY ) {
- strcpy(msg.text, "4 GD-5424+ FIFO Demand Threshold\n" );
- return;
- }
-
-
- uchar _SR16 = read_SR( 0x16 ) & 0x0F; // 0000 XXXX
- uchar new_SR16= 0x0F; // Default to 15 FIFO slots
-
- if ( param[ 0 ] != NULL )
- new_SR16 = (uchar)atoi( param[ 0 ] );
-
- sprintf( msg.text, "Old FIFO threshold = %u ", _SR16 );
-
- switch ( cmd ) {
- case _SET: _SR16 = read_SR( 0x16 ) & 0xF0; // DD00 0000
- write_SR( 0x16, ( new_SR16 & 0x0F ) | _SR16 );
- sprintf( msg.temp, "\nNew FIFO = %u ", new_SR16 );
- strcat ( msg.text, msg.temp );
- break;
- case _GET: case _HELP:
- sprintf( msg.temp, "\nFIFO threshold (GD-5424 and up) %s%s%s",
- "\nTriggering level for CRT to re-fill CRT FIFO (0-15d)",
- "\n\t( lower value = more frequent re-fills )",
- "\n\tAllowable input: 0-15 (decimal)");
- strcat ( msg.text, msg.temp );
- break;
- default:
- sprintf( msg.text, "_GD5424::_fxn4(cmd) UNRECOGNIZED cmd.");
- status = EXIT_FAILURE;
- }
- } */
-
-
-
- void
- _GD5424::_fxn3( int cmd ) // RDY Delay for Memory Write
- {
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "3 GD-5424/6/8/9 RDY Delay for mem-write "
- << "(local-bus only)\n" << ends;
- return;
- }
-
-
- uchar _SR16 = ( read_SR( 0x16 ) >> 4 ) & 0x03; // Read _SR16 register
- uchar new_RDY= 0x03; // Default to 2T delay
- uchar _is5429 = ( strcmpi( id.chipset, "GD-5429" ) == 0 );
- // _is5429 is a status-variable, 0 = not 5429
-
- if ( param[ 0 ] != NULL )
- new_RDY = (uchar)atoi( param[ 0 ] );
-
- msgout << "Old RDY write-mem delay = " << (int)( 2 - _is5429 + _SR16 )
- << "T (" << (int)( _SR16 ) << ") ";
- // sprintf( msg.text, "Old RDY write-mem delay = %uT (%ud) ", ( 2 -
- // _is5429 + _SR16 ), _SR16 ) ;
-
- switch ( cmd ) {
- case _SET: _SR16 = read_SR( 0x16 ) & 0xCF; // 00DD 0000
- write_SR( 0x16, ( ( new_RDY << 4 ) & 0x30 ) | _SR16 );
- msgout << "\nNew delay = " << (int)( 2 - _is5429 + new_RDY )
- << "T (" << (int)( new_RDY ) << ") ";
- // sprintf( msg.temp, "\nNew delay = %uT (%ud) ", 2 - _is5429 +
- // new_RDY, new_RDY );
- // strcat ( msg.text, msg.temp );
- break;
- case _GET: case _HELP: msgout << "\n(local-bus only)"
- << " Actual LRDY I/O clock delays (T) / XXd"
- << "\n(where XXd is INPUT value in decimal.)";
- if ( _is5429 )
- msgout << "\n\t1T/00\n\t2T/01\n\t3T/02\n\t4T/03";
- else
- msgout << "\n\t2T/00\n\t3T/01\n\t4T/02\n\t5T/03";
- break;
- default: msgout << "_GD5424::_fxn3(cmd) UNRECOGNIZED cmd.";
- status = EXIT_FAILURE;
- }
- msgout << ends;
- }
-
-
- //-------------------- Cirrus GD-543x functions --------------------------
- void
- _GD543x::_fxn2( int cmd ) // LRDY delay for VL-bus only
- { // 0600 0000 bit6 of _SR16 = LRDY delay
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "2 GD-543x RDY delay for I/O (local-bus only)\n"
- << ends;
- return;
- }
-
- uchar _SR16 = read_bit( _SRindex, 0x16, 6 ); // Read bit6 _SR16 register
- uchar new_RDY= 0x01; // Default to 2T READ/ 1T WRITE delay
-
- if ( param[ 0 ] != NULL )
- new_RDY = (uchar)atoi( param[ 0 ] ) ;
-
- sprintf( msg.text, "Old vl-bus LRDY R/W delay = %uT/%uT (%ud) ", 1 +
- _SR16, _SR16, _SR16 );
-
- switch ( cmd ) {
- case _SET:
- write_bit( _SRindex, 0x16, 6, new_RDY );
- sprintf( msg.temp, "\nNew R/W delay = %uT/%uT (%ud) ", 1 +
- new_RDY, new_RDY, new_RDY );
- strcat ( msg.text, msg.temp );
- break;
- case _GET: case _HELP:
- sprintf( msg.temp,"\n(only applicable in VL-bus setup.)%s",
- "\n\t1T read/0T write - 00\n\t2T read/1T write - 01");
- strcat ( msg.text, msg.temp );
- break;
- default:
- sprintf( msg.text, "_GD543x::_fxn2(cmd) UNRECOGNIZED cmd.");
- status = EXIT_FAILURE;
- }
- }
-
-
- void
- _GD543x::_fxn3( int cmd ) // LRDY Delay for Memory Cycles
- { // LRDY Delay = bit4 of _SR16
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "3 GD-543x RDY Delay for mem-write (local-bus only)\n"
- << ends;
- return;
- }
-
- uchar _SR16 = read_bit( _SRindex, 0x16, 4 ); // Read bit4 _SR16 register
- uchar new_RDY= 0x01; // Default to 2T-1T R/W delay
-
- if ( param[ 0 ] != NULL )
- new_RDY = (uchar)atoi( param[ 0 ] );
-
- sprintf( msg.text, "Old LRDY R/W mem delay = %uT/%uT (%ud) ", 1 +
- _SR16, _SR16, _SR16 ) ;
-
- switch ( cmd ) {
- case _SET:
- write_bit( _SRindex, 0x16, 4, new_RDY );
- sprintf( msg.temp, "\nNew R/W delay = %uT/%uT (%ud) ", 1 +
- new_RDY, new_RDY, new_RDY ) ;
- strcat ( msg.text, msg.temp );
- break;
- case _GET: case _HELP:
- sprintf( msg.temp, "\n(local-bus only)%s",
- "\nRead delay / Write delay\n\t1T/0T - 00\n\t2T/1T - 01" );
- strcat( msg.text, msg.temp );
- break;
- default:
- sprintf( msg.text, "_GD543x::_fxn3(cmd) UNRECOGNIZED cmd.");
- status = EXIT_FAILURE;
- }
- }
-
-
- void
- _GD5434::_mclk( int cmd )
- {
- uchar _SR1F = read_SR ( 0x1F ) & 0x3F; // Read _SR1F register
- uchar new_MCLK = _SR1F; // New MCLK byte
- union REGS reg;
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "0 GD-5434 MCLK memory clock setting\n" << ends;
- return;
- }
- // sprintf( msg.text, "Current MCLK = %.2fMHz (%02dd)", get_mclkfreq(),
- // _SR1F );
- msgout.precision( 2 );
- msgout << "Old MCLK = " << get_mclkfreq() << "MHz (" << (int)(_SR1F)
- << "d)";
-
- if ( param[ 0 ] != NULL ) // Only the 1st parameter is used
- new_MCLK = ( (uchar) atoi( param[ 0 ] ) ) & 0x3F;
-
- switch ( cmd ) {
- case _SET : _SR1F = read_SR( 0x1F) & 0xC0; // XX00 0000
- // Now perform a READ/MODIFY/WRITE to _SR1F
- write_SR( 0x1F, _SR1F | new_MCLK );
- msgout << "\nNew MCLK = " << get_mclkfreq() << "MHz ("
- << (int)( new_MCLK ) << "d)";
- // sprintf( msg.temp, "\nNew MCLK = %.2fMHz (%02dd) ",
- // get_mclkfreq(), new_MCLK );
- // strcat( msg.text, msg.temp );
- break;
- case _GET : case _HELP: msgout << "\nGD-5434 max = 50MHz, "
- << "GD-5434revE max = 60MHz\nInput = 0-63dec, example values "
- << ": \n\t23d = 41.17MHz\n\t25d = 44.74MHz"
- << "\n\t28d = 50.11MHz\n\tOther values ok.\n\t**WARNING** "
- << "GD-5434's video BIOS resets MCLK on every mode change!";
- // strcat( msg.text, msg.temp );
- break;
- default:
- msgout << "_GD5434::_mclk(cmd) UNRECOGNIZED cmd.";
- status = EXIT_FAILURE;
- }
- msgout << ends;
- }
-
-
- void
- _GD5436::_fxn1( int cmd ) // Enable 8-MCLK EDO Timing
- { // bit2 of _GR18, 0 = no, 1 = 8-MCLK EDO timing
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "1 GD-5436/46 8-MCLK EDO DRAM timing\n" << ends;
- return;
- }
- uchar new_EDO = read_bit( _GRindex, 0x18, 2 ); // Default to old val
-
- sprintf( msg.text, "Old 8-MCLK EDO timing = %s", bitstat( new_EDO ) );
-
- if ( param[ 0 ] != NULL )
- new_EDO = (uchar)atoi( param[ 0 ] );
-
- switch ( cmd ) {
- case _SET: write_bit( _GRindex, 0x18, 2, new_EDO );
- sprintf( msg.temp, "\n8-MCLK EDO timing is now %s ",
- bitstat( new_EDO ) );
- strcat ( msg.text, msg.temp );
- break;
- case _GET: case _HELP:
- sprintf( msg.temp, "\n8-MCLK EDO Timing\n\t1 = enable%s%s",
- "\n\t0 = disable\nDisable for FPM-DRAM, activate for EDO-DRAM timing",
- "\n(Increased delay may permit higher MCLK-frequencies" );
- strcat ( msg.text, msg.temp );
- break;
- default:
- sprintf( msg.text, "_GD5436::_fxn1(cmd) UNRECOGNIZED cmd.");
- status = EXIT_FAILURE;
- }
- }
-
-
- void
- _GD5436::_fxn2( int cmd ) // Single Refresh Cycle
- { // bit3 of _GR18, 0 = standard timing, 1 = single-refresh cycle
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "2 GD-5436/46 RAM refresh-cycle timing\n" << ends;
- return;
- }
- uchar new_CYC = read_bit( _GRindex, 0x18, 3 ); // Default to old val
-
- sprintf( msg.text, "Single-refresh cycle timing = %s",
- bitstat( new_CYC ) );
-
- if ( param[ 0 ] != NULL )
- new_CYC = (uchar)atoi( param[ 0 ] );
-
- switch ( cmd ) {
- case _SET: write_bit( _GRindex, 0x18, 3, new_CYC );
- sprintf( msg.temp, "\nSingle-cycle refresh timing is now %s.",
- bitstat( new_CYC ) );
- strcat ( msg.text, msg.temp );
- break;
- case _GET: case _HELP:
- sprintf( msg.temp, "\nSingle-cycle refresh\n\t1 = enable%s%s",
- "\n\t0 = disable\n\nEnabling single-cycle refresh ",
- "increases available memory-bandwidth." );
- strcat ( msg.text, msg.temp );
- break;
- default:
- sprintf( msg.text, "_GD5436::_fxn2(cmd) UNRECOGNIZED cmd.");
- status = EXIT_FAILURE;
- }
- }
-
-
- _GD5462::_GD5462( vga_info info ) : vga( info )
- {
- // First, get and store original MMIO0 base-address
- // We need to keep it, because it'll be changed later
- baseio.b.b0 = read_cbyte( 0x10 +0 ); // Read PCICFG$10, bits 7:0
- baseio.b.b1 = read_cbyte( 0x10 +1 ); // Read PCICFG$11, bits 15:8
- baseio.b.b2 = read_cbyte( 0x10 +2 ); // Read PCICFG$12, bits 23:16
- baseio.b.b3 = read_cbyte( 0x10 +3 ); // Read PCICFG$13, bits 31:24
- // Byte3 = most-significant byte, Byte0= least-significant)
-
- // Actually, the Cirrus Logic mmio0 spans bits 31:15 at PCICFG$10
- // We don't need to store b0. We only need to store bit7 of b1
- // MMIO aperature = 32KB (mmio0 address = 32kB granularity)
- // For aperature at A000:0000 (absolute offset 6556360 decimal)
- // Must set MMIO[31:15] = $14 (hex)
- // --> translates into b3 = 0x0A, b2 = 0, b1[bit 7] = 0
-
-
- // Now we have to enable I/O access to MMIO registers
- pci_command.b.b0 = read_cbyte( 0x04 ); // Preserve original value
- pci_command.b.b1 = read_cbyte( 0x05 ); // Preserve original value
-
- write_cbyte( 0x04, pci_command.b.b0 | 0x01 ); // Write out XXXX XXX1
-
- framebuffer = (uchar*)MK_FP( 0xA000, 0x0000 );
- // Set framebuffer to point to VGA framebuffer address 0xA0000
-
- }
-
-
- _GD5462::~_GD5462()
- {
- // Restore original MMIO aperature location
- write_cbyte( 0x10, baseio.b.b0 );
- write_cbyte( 0x11, baseio.b.b1 );
- write_cbyte( 0x12, baseio.b.b2 );
- write_cbyte( 0x13, baseio.b.b3 );
-
- // Now restore pci_command register
- write_cbyte( 0x04, pci_command.b.b0 );
- write_cbyte( 0x05, pci_command.b.b1 );
- }
-
-
- message
- _GD5462::_info( void )
- {
- INITMSG( msg.text );
-
- msgout << "IO config address = 0x" ; // 32-bit absolute byte address
- hexout( msgout, baseio.b.b3 ); // print reg.h.bl in "XX" format
- hexout( msgout, baseio.b.b2 );
- msgout << " ";
- if ( baseio.b.b1 & 0x80 ) // Is bet7 of b1 set?
- msgout << "8000"; // Yup! +32Kbyte offset
- else
- msgout << "0000"; // Nope! No such offset
-
- msgout << ends ;
- return msg;
- }
-
-
- uchar
- _GD5462::read_cbyte( const uchar index )
- {
- uchar value, status = TRUE;
-
- status = pci_bios->read_cbyte( pci_vga, index, &value );
- return value;
- }
-
-
- uchar
- _GD5462::write_cbyte( const uchar index, const uchar value )
- {
- uchar status= TRUE;
-
- if ( pci_bios->write_cbyte( pci_vga, index, value ) != 0 )
- status = FALSE;
-
- return status;
- }
-
- uchar
- _GD5462::get_mclkbyte( void )
- {
- uchar mclk_byte;
- // Set MMIO0 aperature to A0000, so it's readable by real-mode apps
- // Actually, the Cirrus Logic mmio0 spans bits 31:15 at PCICFG$10
- // We don't need to store b0. We only need to store bit7 of b1
- // MMIO aperature = 32KB (mmio0 address = 32kB granularity)
- // For aperature at A000:0000 (absolute offset 6556360 decimal)
- // Must set MMIO[31:15] = $14 (hex)
- // --> translates into b3 = 0x0A, b2 = 0, b1[bit 7] = 0
-
- write_cbyte( 0x12, 0x0A ); // base-address[8:1] = 0x0A
- write_cbyte( 0x13, 0x00 ); // base-address[16:9] = 0x00
- write_cbyte( 0x11, read_cbyte( 0x11 ) & 0x7F );
- // bit7=0, or base-address[0] = 0
-
- mclk_byte = *( framebuffer + 0x8C ); // read MMIO0 offset 0x8C
-
- // Restore MMIO0 aperature to original value
- write_cbyte( 0x11, baseio.b.b1 );
- write_cbyte( 0x12, baseio.b.b2 );
- write_cbyte( 0x13, baseio.b.b3 );
-
- return mclk_byte;
- }
-
-
- void
- _GD5462::_mclk( int cmd )
- {
- union {
- uchar byte; // MCLK register byte
- struct {
- unsigned mult : 5; // RAMBUS multiplier, 5-bits
- unsigned other : 3;
- } x;
- } mclk;
-
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "0 GD-546X RAMBUS clock setting\n" << ends;
- return;
- }
-
- mclk.byte = get_mclkbyte(); // Get mclk_byte
-
- msgout.precision( 2 );
- msgout << "Old RAMBUS clock = " << ( _OSC * mclk.x.mult ) << " MHz ("
- << (int)( mclk.x.mult ) << "d)";
-
- if ( param[ 0 ] != NULL ) // Only the 1st parameter is used
- mclk.x.mult = (unsigned) atoi( param[ 0 ] ) & 0x1F;
-
- switch ( cmd ) {
- case _SET : // First, set MMIO address to A000:0000
- write_cbyte( 0x12, 0x0A ); // base-address[15:0] = 0x000A
- write_cbyte( 0x13, 0x00 );
- write_cbyte( 0x11, read_cbyte( 0x11 ) & 0x7F );
- // bit7=0, or base-address[0] = 0
-
- *( framebuffer + 0x8C ) = mclk.byte;
- // Write mclk_byte -> MMIO0 offset 0x8C
-
- // Restore MMIO0 aperature to original value
- write_cbyte( 0x11, baseio.b.b1 );
- write_cbyte( 0x12, baseio.b.b2 );
- write_cbyte( 0x13, baseio.b.b3 );
-
- mclk.byte = get_mclkbyte(); // Re-read mclk_byte
- msgout << "\nNew RAMBUS clock = " << ( _OSC * mclk.x.mult ) <<
- " MHz (" << (int)( mclk.x.mult ) << "d)";
- break;
- case _GET : case _HELP: msgout
- << "\nNote: GD-546X maximum RAMBUS clock (BCLK) = "
- << "258MHz (18d),\n\tInput = 7-22dec, example values :"
- << "\n\t18 = 257.73MHz\n\t20 = 286.36MHz\n\tOther values ok."
- << "\n\nWARNING! Win95 drivers reset RAMBUS clock! See "
- << "546X.TXT for details!";
-
- break;
- default:
- msgout << "_GD5462::_mclk(cmd) UNRECOGNIZED cmd.";
- status = EXIT_FAILURE;
- }
- msgout << ends;
- }
-
-
- void
- _GD5464::_fxn2( int cmd ) // PCI Master Latency Timer Register
- { // PCI Config $0D[7:3]
- union {
- uchar byte; // PCI Master latency timer register byte
- struct {
- unsigned other : 3;
- unsigned timer : 5; // PCI latency timer, 5-bits
- } x;
- } pcfg;
-
- INITMSG( msg.text );
-
- if ( cmd == _QUERY ) {
- msgout << "2 GD-5464 PCI Master Latency Timer\n" << ends;
- return;
- }
-
- pcfg.byte = read_cbyte( 0x0D); // Get pcfg_byte
-
- msgout << "Old Latency Timer=" << (int)( pcfg.x.timer ) << " cycle(s)";
-
- if ( param[ 0 ] != NULL ) // Only the 1st parameter is used
- pcfg.x.timer = (unsigned) atoi( param[ 0 ] ) & 0x1F;
-
- switch ( cmd ) {
- case _SET : write_cbyte( 0x0D, pcfg.byte );
-
- pcfg.byte = read_cbyte( 0x0D ); // Re-read pcfg_byte
- msgout << "\nNew Latency Timer=" << (int)( pcfg.x.timer ) <<
- " cycle(s)";
- break;
- case _GET : case _HELP: msgout
- << "\nGD-5464 PCI Latency Timer\n Controls latency when "
- << "GD-5464 acts as a PCI-bus master.\n\tInput = 0-31 "
- << "(number of PCI clock cycles)";
- break;
- default:
- msgout << "_GD5464::_fxn2(cmd) UNRECOGNIZED cmd.";
- status = EXIT_FAILURE;
- }
- msgout << ends;
- }
-