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

📄 vga.c

📁 nucleus_arm.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
	
	switch(current_mode)
	{
		case 0x04:
		case 0x05:
			{
				offset = (y * bios_modes[current_mode].max_x) +  (x / 4) + (8152 * (y & 1));
				mask = 0xC0 >> ((x & 3) * 2);
				tmp = bios_modes[current_mode].video_ptr[offset];
				tmp = (tmp & (mask & 0xFF)) | (col_mask[color] & mask);
				bios_modes[current_mode].video_ptr[offset] = tmp;
			} break;
		case 0x06:
			{
				offset = ((y * bios_modes[current_mode].max_x) + x) / 8 + (8152 * (y & 1));
				mask = 0x80 >> (x & 7);				
				if (color)
					bios_modes[current_mode].video_ptr[offset] |= mask;
				else
					bios_modes[current_mode].video_ptr[offset] &= (mask & 0xFF);
			} break;
		case 0x11:
			{
				offset = ((y * bios_modes[current_mode].max_x) + x) / 8;
				mask = 0x80 >> (x & 7);
				if (color)
					bios_modes[current_mode].video_ptr[offset] |= mask;
				else
					bios_modes[current_mode].video_ptr[offset] &= (mask & 0xFF);
			} break;
		case 0x0D:
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x12:
			{
				if (current_mode == 0x0F)
				{
					if (color > 1)	// if bit 0, set bit 2
						color += 2;
				}
				
				offset = ((y * bios_modes[current_mode].max_x) + x) / 8;
				mask = 0x80 >> (x & 7);
				// load S/R with color
				outportb(GRA_I, 0);		outportb(GRA_D, color);
				// open memory for S/R
				outportb(GRA_I, 1);		outportb(GRA_D, 0x0F);
				// load bitmask
				outportb(GRA_I, 8);
				outportb(GRA_D, mask);
				// write color
				bios_modes[current_mode].video_ptr[offset]--;
				// reset
				outportb(GRA_I, 1);		outportb(GRA_D, 0);
				outportb(GRA_I, 8);		outportb(GRA_D, 0xFF);
			} break;
		case 0x13:
			{
				offset = ((y * bios_modes[current_mode].max_x) + x) / 4;
				outportb(SEQ_I, 2);				// index map register
				outportb(SEQ_D, 1 << (x & 3));	// select memory level
				bios_modes[current_mode].video_ptr[offset] = color;
			} break;
	}
}

static unsigned vga_getpixel(unsigned int x, unsigned int y)
{
	switch(current_mode)
	{
		case 0x13:
			{
				unsigned int offset;
				
				offset = (y * bios_modes[current_mode].max_x * 2) + (x / 4);
				outportb(GRA_I, 4);			// index map register select
				outportb(GRA_D, x & 3);		// select memory level
				return bios_modes[current_mode].video_ptr[offset];
			} break;
	}
	return 0;
}

static char vga_setmode(unsigned int mode)
{
	switch(mode)
	{
		case 0x00:		// text, 40x25, 16 cols
			{
				write_regs(g_mode_00);
				setpalette16();
			} break;
		case 0x01:		// text, 40x25, 16 cols
			{
				write_regs(g_mode_01);
				setpalette16();
			} break;
		case 0x02:		// text, 80x25, 16 cols
			{
				write_regs(g_mode_02);
				setpalette16();
			} break;
		case 0x03:		// text, 80x25, 16 cols
			{
				write_regs(g_mode_03);
				setpalette16();
			} break;
		case 0x04:		// 320x200x4
			{
				write_regs(g_mode_04);
				setpalette4();
			} break;
		case 0x05:		// 320x200x4
			{
				write_regs(g_mode_05);
				/* to make CGA graphics work like other graphics modes... */
				/* 1) turn off screwy CGA addressing */
				outportb(CRT_I, 0x17);
				outportb(CRT_D, inportb(CRT_D) | 1);
				/* 2) turn off doublescan */
				outportb(CRT_I, 9);
				outportb(CRT_D, inportb(CRT_D) & ~0x80);
				/* 3) move the framebuffer from B800:0000 to A000:0000 */
				outportb(GRA_I, 6);
				outportb(GRA_D, inportb(GRA_I) & ~0x0C);
				/* set new address */
				bios_modes[mode].video_ptr = (char *)(0xA0000);
				setpalette4();
			} break;
		case 0x07:		// text, 80x25, 16 cols
			{ 
				write_regs(g_mode_07);
			} break;
		case 0x0D:	// 320x200x16
			{
				write_regs(g_mode_0D);
				setpalette16();
			} break;
		case 0x0E:	// 640x200x16
			{
				write_regs(g_mode_0E);
				setpalette16();
			} break;
		case 0x0F:	// 640x350xMono
			{
				write_regs(g_mode_0F);
			} break;
		case 0x10:	// 640x350x16
			{
				write_regs(g_mode_10);
				setpalette16();
			} break;
		case 0x11:	// 640x480x2		
			{
				write_regs(g_mode_11);
			} break;	
		case 0x12:	// 640x480x16
			{
				write_regs(g_mode_12);
				setpalette16();
			} break;
		case 0x13:	// 320x200x256 aka ModeX
			{
				write_regs(g_mode_13);
				setpalette256();
				// 1) turn off Chain-4 addressing
				// bit 3, memory mode register = 0
				outportb(SEQ_I, 0x04);
				outportb(SEQ_D, inportb(SEQ_D) & ~0x08);
				// 2) turn off doubleword clocking
				// bit 6, underline location register = 0, double word mode off
				outportb(CRT_I, 0x14);
				outportb(CRT_D, inportb(CRT_D) & ~0x40);
				// 3) turn off word clocking in case it's on
				// bit 6, mode control register = 1, byte mode on
				outportb(CRT_I, 0x17);
				outportb(CRT_D, inportb(CRT_D) | 0x40);
			} break;
		default:
			{
				return -0x01;				
			}			
	}
	if (bios_modes[mode].font_height >= 16)
    	memcpy(font_buf, g_8x16_font, 4096);
    else
    	memcpy(font_buf, g_8x8_font, 2048);
		
	if (bios_modes[current_mode].graphic && graphic_card > GR_EGA)
	{
		// restore font data in plane 2
		outportb(SEQ_I, 0x02);
		outportb(SEQ_D, 0x04);
		// restore font data in plane 3, trident
		outportb(SEQ_I, 0x02);
		outportb(SEQ_D, 0x08);
	}
	
	current_mode = mode;
	/* tell the BIOS what we've done, so BIOS text output works OK */		
//	pokew(0x40, 0x4A, bios_modes[mode].max_x);	/* columns on screen */
//	pokew(0x40, 0x4C, bios_modes[mode].max_x * bios_modes[mode].max_y * 2); /* framebuffer size */
//	pokew(0x40, 0x50, 0);		/* cursor pos'n */
//	pokeb(0x40, 0x60, bios_modes[mode].font_height - 1);	/* cursor shape */
//	pokeb(0x40, 0x61, bios_modes[mode].font_height - 2);
//	pokeb(0x40, 0x84, bios_modes[mode].max_x - 1);	/* rows on screen - 1 */
//	pokeb(0x40, 0x85, bios_modes[mode].font_height);		/* char height */
		
	return 0x00;
}

static unsigned int vga_getmode(void)
{
	return current_mode;
}

char find6845(unsigned int addr)
{
	unsigned char tmp, result;

	outportb(addr, 0x0F);
	tmp = inportb(addr + 1);
	
	outportb(addr, 0x0F);
	outportb(addr + 1, 0x66);
	
	delay(100);
	
	result = (inportb(addr + 1) == 0x66);
	outportb(addr + 1, tmp);
	
	return result;
}

char findMono(void)
{
	unsigned char  tmp1, tmp2;
	unsigned int timeout;

	if (find6845(CRT_IM))
	{
		tmp1 = inportb(CRT_IM + 6) & 0x80;
		timeout = 100;
		do {
			tmp2 = inportb(CRT_IM + 6) & 0x80;
			delay(1);
		} while (tmp1 != tmp2 || ! timeout--);
		if (tmp1 != tmp2)
			return GR_HERC;
		return GR_MONO;
	}
	return GR_UNKNOWN;
}

char findCGA(void)
{
	return find6845(CRT_IC) ? GR_CGA : GR_UNKNOWN;
}

static unsigned int vga_test(void)
{
 	unsigned char save, back;
 	
	if (vga_card == GR_UNKNOWN)
	{	// Check if a DAC is present
		save = inportb(PEL_IW);
		graphic_delay();
		outportb(PEL_IW, ~ save);
		graphic_delay();
		back = inportb(PEL_IW);
		graphic_delay();
		outportb(PEL_IW, save);
		save = ~save;
		vga_card = (back == save) ? GR_VGA : GR_EGA;
	}
	if (vga_card == GR_EGA)
	{
		vga_card = findMono();
		if (vga_card == GR_UNKNOWN)
			vga_card = findCGA();
	}
	return 1;	// always true
}

static unsigned int vga_memory(void)
{
	return 32;
}

static char * vga_get_name(void)
{
	switch(vga_card)
	{
		case GR_UNKNOWN:	return "Unknown";
		case GR_MONO:		return "Mono";
		case GR_HERC:		return "HERC";
		case GR_CGA:		return "CGA";
		case GR_EGA:		return "EGA";
		case GR_VGA:		return "VGA";
	}
	return "Unknown";
}

GraphicDriver vga_driver =
{
	vga_test,
	vga_get_name,
	vga_memory,
	vga_setmode,
	vga_getmode,
	NULL,
	NULL,
	NULL,
	NULL,
	vga_putch,
	vga_wherex,
	vga_wherey,
	vga_max_x,
	vga_max_y,
	vga_max_col,
	vga_gotoxy,
	vga_scroll,
	vga_clrscr
};

char Check_VGA(GraphicDriver * driver)
{
	*driver = vga_driver;
	return (vga_test());
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -