📄 modetbl.cpp
字号:
{
unsigned long value, gate, clock;
unsigned long palette_ram;
unsigned long fb_size, offset;
// Get current power configuration.
gate = peekRegisterDWord(CURRENT_POWER_GATE);
clock = peekRegisterDWord(CURRENT_POWER_CLOCK);
// Program panel.
if (register_table->display == PANEL)
{
// Program clock, enable display controller.
gate = FIELD_SET(gate, CURRENT_POWER_GATE, DISPLAY, ENABLE);
clock &= FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SELECT)
& FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_DIVIDER)
& FIELD_CLEAR(CURRENT_POWER_CLOCK, P2XCLK_SHIFT);
setPower(gate, clock | register_table->clock);
// Calculate frame buffer address.
value = 0;
fb_size = register_table->fb_width * register_table->height;
if (FIELD_GET(peekRegisterDWord(CRT_DISPLAY_CTRL),
CRT_DISPLAY_CTRL,
PLANE) == CRT_DISPLAY_CTRL_PLANE_ENABLE)
{
value = FIELD_GET(peekRegisterDWord(CRT_FB_ADDRESS),
CRT_FB_ADDRESS,
ADDRESS);
if (fb_size < value)
{
value = 0;
}
else
{
value += FIELD_GET(peekRegisterDWord(CRT_FB_WIDTH),
CRT_FB_WIDTH,
OFFSET)
* (FIELD_GET(peekRegisterDWord(CRT_VERTICAL_TOTAL),
CRT_VERTICAL_TOTAL,
DISPLAY_END) + 1);
}
}
// Program panel registers.
pokeRegisterDWord(PANEL_FB_ADDRESS,
FIELD_SET(0, PANEL_FB_ADDRESS, STATUS, PENDING) |
FIELD_SET(0, PANEL_FB_ADDRESS, EXT, LOCAL) |
FIELD_VALUE(0, PANEL_FB_ADDRESS, ADDRESS, value) );
pokeRegisterDWord(PANEL_FB_WIDTH,
FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH,
register_table->fb_width) |
FIELD_VALUE(0, PANEL_FB_WIDTH, OFFSET,
register_table->fb_width) );
pokeRegisterDWord(PANEL_WINDOW_WIDTH,
FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH,
register_table->width) |
FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, 0) );
pokeRegisterDWord(PANEL_WINDOW_HEIGHT,
FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT,
register_table->height) |
FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, 0) );
pokeRegisterDWord(PANEL_PLANE_TL,
FIELD_VALUE(0, PANEL_PLANE_TL, TOP, 0) |
FIELD_VALUE(0, PANEL_PLANE_TL, LEFT, 0) );
pokeRegisterDWord(PANEL_PLANE_BR,
FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM,
register_table->height - 1) |
FIELD_VALUE(0, PANEL_PLANE_BR, RIGHT,
register_table->width - 1) );
pokeRegisterDWord(PANEL_HORIZONTAL_TOTAL,
register_table->horizontal_total);
pokeRegisterDWord(PANEL_HORIZONTAL_SYNC,
register_table->horizontal_sync);
pokeRegisterDWord(PANEL_VERTICAL_TOTAL,
register_table->vertical_total);
pokeRegisterDWord(PANEL_VERTICAL_SYNC,
register_table->vertical_sync);
// Program panel display control register.
value = peekRegisterDWord(PANEL_DISPLAY_CTRL)
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE)
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE)
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING)
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE)
& FIELD_CLEAR(PANEL_DISPLAY_CTRL, FORMAT);
pokeRegisterDWord(PANEL_DISPLAY_CTRL,
value | register_table->control);
// Palette RAM.
palette_ram = PANEL_PALETTE_RAM;
// Turn on panel.
panelPowerSequence(PANEL_ON, 4);
}
// Program CRT.
else
{
// Program clock, enable display controller.
gate = FIELD_SET(gate, CURRENT_POWER_GATE, DISPLAY, ENABLE);
clock &= FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_SELECT)
& FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_DIVIDER)
& FIELD_CLEAR(CURRENT_POWER_CLOCK, V2XCLK_SHIFT);
setPower(gate, clock | register_table->clock);
// Turn on DAC.
pokeRegisterDWord(MISC_CTRL, FIELD_SET(peekRegisterDWord(MISC_CTRL),
MISC_CTRL,
DAC_POWER,
ENABLE));
// On Rev. A0 we need to invert polarity for CRT tristate.
if (rev() == 0xA0)
{
pokeRegisterDWord(SYSTEM_CTRL,
FIELD_SET(peekRegisterDWord(SYSTEM_CTRL),
SYSTEM_CTRL,
CRT_TRISTATE,
ENABLE));
}
else if (rev() == 0xB0)
{
}
else
{
pokeRegisterDWord(SYSTEM_CTRL,0);
}
#if CMDLIST_IN_SYS_MEM
pokeRegisterDWord(SYSTEM_CTRL,
FIELD_INIT(SYSTEM_CTRL, PCI_MASTER, START )
);
#endif
// Calculate frame buffer address.
value = 0;
fb_size = register_table->fb_width * register_table->height;
if (FIELD_GET(peekRegisterDWord(PANEL_DISPLAY_CTRL),
PANEL_DISPLAY_CTRL,
PLANE) == PANEL_DISPLAY_CTRL_PLANE_ENABLE)
{
value = FIELD_GET(peekRegisterDWord(PANEL_FB_ADDRESS),
PANEL_FB_ADDRESS,
ADDRESS);
if (fb_size < value)
{
value = 0;
}
else
{
value += FIELD_GET(peekRegisterDWord(PANEL_FB_WIDTH),
PANEL_FB_WIDTH,
OFFSET)
* FIELD_GET(peekRegisterDWord(PANEL_WINDOW_HEIGHT),
PANEL_WINDOW_HEIGHT,
HEIGHT);
}
}
// Program CRT registers.
pokeRegisterDWord(CRT_FB_ADDRESS,
FIELD_SET(0, CRT_FB_ADDRESS, STATUS, PENDING) |
FIELD_SET(0, CRT_FB_ADDRESS, EXT, LOCAL) |
FIELD_VALUE(0, CRT_FB_ADDRESS, ADDRESS, value) );
pokeRegisterDWord(CRT_FB_WIDTH,
FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH,
register_table->fb_width) |
FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET,
register_table->fb_width) );
pokeRegisterDWord(CRT_HORIZONTAL_TOTAL,
register_table->horizontal_total);
pokeRegisterDWord(CRT_HORIZONTAL_SYNC,
register_table->horizontal_sync);
pokeRegisterDWord(CRT_VERTICAL_TOTAL,
register_table->vertical_total);
pokeRegisterDWord(CRT_VERTICAL_SYNC,
register_table->vertical_sync);
// Program CRT display control register.
value = peekRegisterDWord(CRT_DISPLAY_CTRL)
& FIELD_CLEAR(CRT_DISPLAY_CTRL, VSYNC_PHASE)
& FIELD_CLEAR(CRT_DISPLAY_CTRL, HSYNC_PHASE)
& FIELD_CLEAR(CRT_DISPLAY_CTRL, SELECT)
& FIELD_CLEAR(CRT_DISPLAY_CTRL, TIMING)
& FIELD_CLEAR(CRT_DISPLAY_CTRL, PLANE)
& FIELD_CLEAR(CRT_DISPLAY_CTRL, FORMAT);
pokeRegisterDWord(CRT_DISPLAY_CTRL,
value | register_table->control);
// Palette RAM.
palette_ram = CRT_PALETTE_RAM;
// Turn on CRT.
setDPMS(DPMS_ON);
}
// In case of 8-bpp, fill palette.
if ((FIELD_GET(register_table->control,
PANEL_DISPLAY_CTRL,
FORMAT) == PANEL_DISPLAY_CTRL_FORMAT_8) |
(FIELD_GET(register_table->control,
CRT_DISPLAY_CTRL,
FORMAT) == CRT_DISPLAY_CTRL_FORMAT_8))
{
// Start with RGB = 0,0,0.
unsigned char red = 0, green = 0, blue = 0;
unsigned long gray = 0;
for (offset = 0; offset < 256 * 4; offset += 4)
{
// Store current RGB value.
pokeRegisterDWord(palette_ram + offset, gray
? RGB24((gray + 50) / 100,
(gray + 50) / 100,
(gray + 50) / 100)
: RGB24(red, green, blue));
if (gray)
{
// Walk through grays (40 in total).
gray += 654;
}
else
{
// Walk through colors (6 per base color).
if (blue != 255)
{
blue += 51;
}
else if (green != 255)
{
blue = 0;
green += 51;
}
else if (red != 255)
{
green = blue = 0;
red += 51;
}
else
{
gray = 1;
}
}
}
}
// For 16- and 32-bpp, fill palette with gamma values.
else
{
// Start with RGB = 0,0,0.
value = 0x000000;
for (offset = 0; offset < 256 * 4; offset += 4)
{
pokeRegisterDWord(palette_ram + offset, value);
// Advance RGB by 1,1,1.
value += 0x010101;
}
}
}
// Mode table.
mode_table_t mode_table[] =
{
// 320 x 240
{ 351, 320, 335, 8, NEGATIVE, 263, 240, 254, 2, NEGATIVE,
6000000, 16000, 60 },
// 400 x 300
{ 528, 400, 420, 64, NEGATIVE, 314, 300, 301, 2, NEGATIVE,
10000000, 18940, 60 },
// 640 x 480
{ 800, 640, 656, 96, NEGATIVE, 525, 480, 490, 2, NEGATIVE,
25175000, 31469, 60 },
{ 832, 640, 664, 40, NEGATIVE, 520, 480, 489, 3, NEGATIVE,
31500000, 37861, 72 },
{ 840, 640, 656, 64, NEGATIVE, 500, 480, 481, 3, NEGATIVE,
31500000, 37500, 75 },
{ 832, 640, 696, 56, NEGATIVE, 509, 480, 481, 3, NEGATIVE,
36000000, 43269, 85 },
// 720 x 540
{ 900, 720, 740, 96, POSITIVE, 576, 540, 545, 2, POSITIVE,
31100000, 34560, 60 },
// 800 x 480
{ 1056, 800, 864, 56, POSITIVE, 525, 480, 490, 2, POSITIVE,
40000000, 31600, 60 },
// 800 x 600
{ 1024, 800, 824, 72, POSITIVE, 625, 600, 601, 2, POSITIVE,
36000000, 35156, 56 },
{ 1056, 800, 840, 128, POSITIVE, 628, 600, 601, 4, POSITIVE,
40000000, 37879, 60 },
{ 1040, 800, 856, 120, POSITIVE, 666, 600, 637, 6, POSITIVE,
50000000, 48077, 72 },
{ 1056, 800, 816, 80, POSITIVE, 625, 600, 601, 3, POSITIVE,
49500000, 46875, 75 },
{ 1048, 800, 832, 64, POSITIVE, 631, 600, 601, 3, POSITIVE,
56250000, 53674, 85 },
// 1024 x 600
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -