⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modetbl.cpp

📁 SM501基于ARMV4/ARMV4I平台
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
	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 + -