📄 vga_gu1.c
字号:
/*-----------------------------------------------------------------------------
* VGA_GU1.C
*
* Version 2.1 - March 3, 2000
*
* This file contains routines to set modes using the VGA registers.
* Since this file is for the first generation graphics unit, it interfaces
* to SoftVGA registers. It works for both VSA1 and VSA2.
*
* History:
* Versions 0.1 through 2.1 by Brian Falardeau.
*
* Copyright (c) 1999-2000 National Semiconductor.
*-----------------------------------------------------------------------------
*/
/* SoftVGA Extended CRTC register indices and bit definitions */
#define CRTC_EXTENDED_REGISTER_LOCK 0x30
#define CRTC_MODE_SWITCH_CONTROL 0x3F
/* BIT DEFINITIONS */
#define CRTC_BIT_16BPP 0x01
#define CRTC_BIT_555 0x02
/* LOCAL ROUTINE DEFINITIONS */
int gu1_detect_vsa2(void);
/*---------------------------------*/
/* MODE TABLES FOR VGA REGISTERS */
/*---------------------------------*/
/* FOR SoftVGA, the CRTC_EXTENDED_ADDRESS_CONTROL (0x43) is always equal to
* 0x03 for a packed linear frame buffer organization. The
* CRTC_EXTENDED_DAC_CONTROL (0x4B) is always equal to 0x03 to work with
* older versions of VSA1 (that needed to specify 8 or 16 bit bus to an
* external RAMDAC. This is not used in VSA2. The clock frequency is
* specified in register 0x4D if clock control (0x4C) is set to 0x80.
* Higher resolutions (1280x1024) use the CRTC_EXTENDED_VERTICAL_TIMING
* register (index 0x41).
*/
gfx_vga_struct gfx_vga_modes[] =
{
/*------------------------------------------------------------------------------*/
{ 640, 480, 60, /* 640x480 */
25, /* 25 MHz clock = 60 Hz refresh rate */
0xE3, /* miscOutput register */
{ 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, /* standard CRTC */
0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xEA, 0x0C, 0xDF, 0x50, 0x00, 0xE7, 0x04, 0xE3, 0xFF },
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
{ 800, 600, 60, /* 800x600 */
40, /* 40 MHz clock = 60 Hz refresh rate */
0x23, /* miscOutput register */
{ 0x7F, 0x63, 0x64, 0x82, 0x6B, 0x1B, 0x72, 0xF0, /* standard CRTC */
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x59, 0x0D, 0x57, 0x64, 0x00, 0x57, 0x73, 0xE3, 0xFF },
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x80, 0x28, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
{ 1024, 768, 60, /* 1024x768 */
65, /* 65 MHz clock = 60 Hz refresh rate */
0xE3, /* miscOutput register */
{ 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xF5, /* standard CRTC */
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x0A, 0xFF, 0x80, 0x00, 0xFF, 0x25, 0xE3, 0xFF },
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x80, 0x41, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
{ 1280, 1024, 60, /* 1280x1024 */
108, /* 108 MHz clock = 60 Hz refresh rate */
0x23, /* miscOutput register */
{ 0xCF, 0x9F, 0xA0, 0x92, 0xAA, 0x19, 0x28, 0x52, /* standard CRTC */
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF },
{ 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x80, 0x6C, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
{ 640, 480, 75, /* 640x480 */
31, /* 31.5 MHz clock = 75 Hz refresh rate */
0xE3, /* miscOutput register */
{ 0x64, 0x4F, 0x4F, 0x88, 0x54, 0x9B, 0xF2, 0x1F, /* standard CRTC */
0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xE1, 0x04, 0xDF, 0x50, 0x00, 0xDF, 0xF3, 0xE3, 0xFF },
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x80, 0x1F, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
{ 800, 600, 75, /* 800x600 */
49, /* 49.5 MHz clock = 75 Hz refresh rate */
0x23, /* miscOutput register */
{ 0x7F, 0x63, 0x63, 0x83, 0x68, 0x11, 0x6F, 0xF0, /* standard CRTC */
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x59, 0x1C, 0x57, 0x64, 0x00, 0x57, 0x70, 0xE3, 0xFF },
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x80, 0x31, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
{ 1024, 768, 75, /* 1024x768 */
79, /* 79 MHz clock = 75 Hz refresh rate */
0xE3, /* miscOutput register */
{ 0x9F, 0x7F, 0x7F, 0x83, 0x84, 0x8F, 0x1E, 0xF5, /* standard CRTC */
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x04, 0xFF, 0x80, 0x00, 0xFF, 0x1F, 0xE3, 0xFF },
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x80, 0x4F, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
{ 1280, 1024, 75, /* 1280x1024 */
135, /* 135 MHz clock = 75 Hz refresh rate */
0x23, /* miscOutput register */
{ 0xCE, 0x9F, 0x9F, 0x92, 0xA4, 0x15, 0x28, 0x52, /* standard CRTC */
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x04, 0xFF, 0xA0, 0x00, 0x00, 0x29, 0xE3, 0xFF },
{ 0x00, 0x51, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, /* extended CRTC */
0x00, 0x00, 0x00, 0x03, 0x80, 0x87, 0x00, 0x00 } },
/*------------------------------------------------------------------------------*/
};
#define GFX_VGA_MODES sizeof(gfx_vga_modes)/sizeof(gfx_vga_struct)
/*-----------------------------------------------------------------------------
* gfx_vga_test_pci
*
* This routine looks for the VGA PCI header. It checks to see that bit 1
* of the command register is writable to know that SoftVGA is trapping
* the PCI config cuscles. If SoftVGA is not emulating the header, the
* hardware will still respond with the proper device ID, etc.
*
* We need to know that SoftVGA is really there so that we can set the
* command register and have the proper effect (enable trapping of VGA).
* Otherwise, if we enable VGA via the PCI header, trapping really won't be
* enabled and the VGA register writes will go out to the external card.
*-----------------------------------------------------------------------------
*/
int gfx_vga_test_pci(void)
{
int softvga = 1;
unsigned long value;
value = gfx_pci_config_read(0x80009400);
if ((value & 0x0000FFFF) != 0x1078) softvga = 0;
else
{
value = gfx_pci_config_read(0x80009404);
gfx_pci_config_write(0x80009404, value | 0x02);
if (!(gfx_pci_config_read(0x80009404) & 0x02)) softvga = 0;
gfx_pci_config_write(0x80009404, value);
}
return(softvga);
}
/*-----------------------------------------------------------------------------
* gfx_vga_get_pci_command
*
* This routine returns the value of the PCI command register.
*-----------------------------------------------------------------------------
*/
unsigned char gfx_vga_get_pci_command(void)
{
unsigned long value;
value = gfx_pci_config_read(0x80009404);
return((unsigned char) value);
}
/*-----------------------------------------------------------------------------
* gfx_vga_set_pci_command
*
* This routine writes the value of the PCI command register. It is used
* to enable or disable SoftVGA.
*
* Bit 0: Enable VGA IO
* Bit 1: Enable VGA memory
*-----------------------------------------------------------------------------
*/
int gfx_vga_set_pci_command(unsigned char command)
{
unsigned long value;
value = gfx_pci_config_read(0x80009404) & 0xFFFFFF00;
value |= (unsigned long) command;
gfx_pci_config_write(0x80009404, value);
return(GFX_STATUS_OK);
}
/*-----------------------------------------------------------------------------
* gfx_vga_seq_reset
*
* This routine enables or disables SoftVGA. It is used to make SoftVGA
* "be quiet" and not interfere with any of the direct hardware access from
* Durango. For VSA1, the sequencer is reset to stop text redraws. VSA2 may
* provide a better way to have SoftVGA sit in the background.
*-----------------------------------------------------------------------------
*/
int gfx_vga_seq_reset(int reset)
{
OUTB(0x3C4, 0);
OUTB(0x3C5, (unsigned char) (reset ? 0x00 : 0x03));
return(GFX_STATUS_OK);
}
/*-----------------------------------------------------------------------------
* gfx_vga_set_graphics_bits
*
* This routine sets the standard VGA sequencer, graphics controller, and
* attribute registers to appropriate values for a graphics mode (packed,
* 8 BPP or greater). This is also known as "VESA" modes. The timings for
* a particular mode are handled by the CRTC registers, which are set by
* the "gfx_vga_restore" routine. Most OSs that use VGA to set modes save
* and restore the standard VGA registers themselves, which is why these
* registers are not part of the save/restore paradigm.
*-----------------------------------------------------------------------------
*/
int gfx_vga_set_graphics_bits(void)
{
/* SET GRAPHICS BIT IN GRAPHICS CONTROLLER REG 0x06 */
OUTB(0x3CE, 0x06);
OUTB(0x3CF, 0x01);
/* SET GRAPHICS BIT IN ATTRIBUTE CONTROLLER REG 0x10 */
INB(0x3BA); /* Reset flip-flop */
INB(0x3DA);
OUTB(0x3C0, 0x10);
OUTB(0x3C0, 0x01);
return(GFX_STATUS_OK);
}
/*-----------------------------------------------------------------------------
* gfx_vga_mode
*
* This routine searches the VGA mode table for a match of the specified
* mode and then fills in the VGA structure with the associated VGA register
* values. The "gfx_vga_restore" routine can then be called to actually
* set the mode.
*-----------------------------------------------------------------------------
*/
int gfx_vga_mode(gfx_vga_struct *vga, int xres, int yres, int bpp, int hz)
{
int i;
unsigned short pitch;
for (i = 0; i < GFX_VGA_MODES; i++)
{
if ((gfx_vga_modes[i].xsize == xres) &&
(gfx_vga_modes[i].ysize == yres) &&
(gfx_vga_modes[i].hz == hz))
{
/* COPY ENTIRE STRUCTURE FROM THE TABLE */
*vga = gfx_vga_modes[i];
/* SET PITCH TO 1K OR 2K */
/* CRTC_EXTENDED_OFFSET index is 0x45, so offset = 0x05 */
pitch = (unsigned short) xres;
if (bpp > 8) pitch <<= 1;
if (pitch <= 1024) pitch = 1024 >> 3;
else pitch = 2048 >> 3;
vga->stdCRTCregs[0x13] = (unsigned char) pitch;
vga->extCRTCregs[0x05] = ((pitch >> 8) & 0x03);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -