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

📄 dispdrv.c

📁 可以加载到嵌入式系统VGA显示驱动程序
💻 C
字号:
/*********************************************************************************\
*				显示驱动 				          *
*							                          *
* Description : 本文件中程序为显示驱动函数,主要包括INT 10H中断和一些显示子程序。 *
*               INT 10H型中断包括:1. VGA寄存器初始化                             *
*                                  2. 清显存                                      *
*                                  3. 硬件光标初始化                              *
*                                  4. 重设模式(重新设置VGA寄存器,切换显示模式)    *
*                                                                                 *
*               显示子程序包括:    1. 在指定位置显示一字符                        *
*                                  2. 在指定位置显示一字符串                      *
*                                  3. 计算光标位置(硬件光标)                      *
*                                                                                 *
\*********************************************************************************/
#include "includes.h"
#include "vga/dispdrv.h"
#include "mouse/ps2mouse.h"
#include "modules/display/disp.h"
#include "modules/display/graphics.h"

INT32U linetab[32];
extern WINDOW win;
extern XWINDOW xwin;
extern MOUSE_STRUC mouse;
extern far INT8 ArrorCur;

/*************本地函数声明************************************/
void interrupt int10(INT16U bp, INT16U di, INT16U si,
			INT16U ds, INT16U es, INT16U dx, 
			INT16U cx, INT16U bx, INT16U ax);
static void setmode(INT8U mode);
static void clearvram(void);
static void setcursortype(INT8U mode);
static void setlinetab(void);
//static void resetmode(INT8U mode);

/**************外部变量声明****************************/
extern OS_EVENT *KtAccessSem;
extern INT16U far crt24[37];
extern INT16U far crt16132[37];
extern INT16U far seq24[15];
extern INT16U far crt1680[37];
extern INT16U far seq16132[15];
extern INT16U far seq1680[15];
extern INT8U  far att[21];
extern INT16U far gra[9];
extern INT16U far recrt24[28];
extern INT16U far reseq24[2];
extern INT16U far recrt16132[28];
extern INT16U far reseq16132[2];
extern INT16U far recrt1680[28];
extern INT16U far reseq1680[2];


void InitLCD(void)
{
	outport(SEQREG, (INT16U)(0x3e<<8)+0x1d);
	outport(SEQREG, (INT16U)(0xb8<<8)+0x1e);
	outport(SEQREG, (INT16U)(0xF0<<8)+0x1f);
	outport(SEQREG, (INT16U)(0x4f<<8)+0x20);
}

#pragma argsused
void interrupt int10(INT16U bp, INT16U di, INT16U si,
			INT16U ds, INT16U es, INT16U dx, 
			INT16U cx, INT16U bx, INT16U ax)
{
	INT8U type, mode;
	
	type = highbyte(ax);
	mode = lowbyte(ax);
	switch(type)
	{
		case 0:
			setmode(mode);
			clearvram();
			setlinetab();
			window(1, 1, 80, 26);
			clrscr();
			window(1, 1, 80, 25);
			Cursor();
			xwindow();
			break;
		case 1:
			setcursortype(mode);			
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		default:
			break;
	}
}

/***********************************************************************\
*			setmode						*
* Description : set display mode					*
* input       : mode = 0-------------24点阵80列				*
*               mode = 1-------------16点阵132列             		*
*               mode = 2-------------16点阵80列				*
*									*
\***********************************************************************/
static void setmode(INT8U mode)
{
	INT16U *p,*p1;
	INT16U cnt, cnt1, i;
	INT8U  *p3;
	
	outportb(MBSREG, 1);		// 允许访问VGA寄存器
	outportb(ADSREG, 8);
	
	switch(mode)
	{
		case 0:
			outportb(MOPREG, 0xA3);		// 垂直同步极性为负,水平同步极性为正, 允许CPU访问显存, CRT I/O地址空间为2DX(用于VGA彩色)
			p = (INT16U *)crt24;
			p1= (INT16U *)seq24;
			cnt = sizeof(crt24)/sizeof(crt24[0]);
			cnt1= sizeof(seq24)/sizeof(seq24[0]);
			break;
		case 1:
			outportb(MOPREG, 0xa3);		// 垂直/水平同步极性都为负
			p = (INT16U *)crt16132;
			p1 = (INT16U *)seq16132;
			cnt = sizeof(crt16132)/sizeof(crt16132[0]);
			cnt1= sizeof(seq16132)/sizeof(seq16132[0]);
			break;
		case 2:
			outportb(MOPREG, 0xa3);
			p = (INT16U *)crt1680;
			p1 = (INT16U *)seq1680;
			cnt = sizeof(crt1680)/sizeof(crt1680[0]);
			cnt1= sizeof(seq1680)/sizeof(crt1680[0]);
			break;
		default:				// 入口参数错误,直接返回
			return;
	}
	for(i=0;i<cnt;i++)				// 初始化CRT寄存器
	{
		outport(CRTREG,*p++);
	}
	
	for(i=0;i<cnt1;i++)				// 初始化定序器
	{
		outport(SEQREG, *p1++);
	}
	p = (INT16U *)gra;				// 初始化图形控制器
	cnt = sizeof(gra)/2;
	for(i=0;i<cnt;i++)
	{
		outport(GRAREG, *p++);
	}
	p3 = (INT8U *)att;
	cnt = sizeof(att);
	inportb(RESREG);
	for(i=0;i<cnt;i++)
	{
		outportb(ATTREG, i);
		outportb(ATTREG, *p3++);
	}
	outportb(VPMREG, 0xff);
	outportb(PMWREG, 0);
	outport(GRAREG, 0x0001);
	outport(SEQREG, 0);
	outport(SEQREG,0x1b00);
	outport(SEQREG, 0xe105);
	inportb(RESREG);
	outportb(ATTREG, 0x20);
}
/***************************************************************\
*		clearvram					*
*								*
* Description : clear 512K vram space, 256K for graphics, 256K  *
*               for text					*
*								*
\***************************************************************/
static void clearvram(void)
{
	cleartext();
	setbkcolor(BLACK);
}

/***************************************************************\
*		setcursortype					*
*								*
* Description : set cursor type					*
*								*
*								*
\***************************************************************/
static void setcursortype(INT8U type)
{
	INT8 x, line, pixel;
	
	outportb(CRTREG, 0x0a);		// 选择光标寄存器
	x = 0;
	if((type&4)==4)			// 是否禁止光标
	{
		x = inport(CRTREG+1);   // 读出当前光标寄存器值
		x |= 0x20;
		outportb(CRTREG, 0xa);
		outportb(CRTREG+1, x);
		return;
	}	
	if((type&1)==1)
		x |= 0x80;		// 固定光标
	else
		x |= 0x40;		// 光标每32场闪烁一次
	outportb(SEQREG, 0x9);
	pixel = inportb(SEQREG+1);
	if((type&2)==2)			// 块壮光标还是线性光标
	{
		line = 0x15;		// 24点阵
		if((pixel&2)==0)
			line = 0xd;	// 16点阵
		x |= line;
		outportb(CRTREG+1, x);	// 写光标开始寄存器
		outportb(CRTREG, 0xb);	// 光标结束寄存器
		outportb(CRTREG+1, x+3);
	}
	else
	{
		outportb(CRTREG+1, x);
		x |= 0x11;
		if(pixel&2)
			x |= 8;
		outportb(CRTREG, 0xb);
		outportb(CRTREG+1, x);
	}
} 

#pragma option -w.


/***************************************************************\
*			cleartext				*
* description : 以图形方式快速清文本屏				*
*								*
*								*
\***************************************************************/
#pragma inline
void cleartext(void)
{
	INT32 *p;
	
	outport(SEQREG, 0x0f0e);
	p = MK_FP(0xa000, 0);
	*p = 0x00800f20UL;
	
	outport(SEQREG, 0x0404);	// 位平面方式
	outport(SEQREG, 0x010e);	// 图形方式共两段,4个文本段对应图形第一段
	outport(GRAREG, 0x0105);	// 锁存器写
	outport(GRAREG, 0x0008);
	outport(GRAREG, 0x0f02);
	outport(GRAREG, 0x0001);
	asm{
		push ds es
		mov ax, 0xa000
		mov es, ax
		mov ds, ax
		mov si, 0xc000
		mov di, 0xc001
		mov cx, 4000h
		cld
		rep movsb
		pop es ds
	}
	outport(SEQREG, 0x0804);
	outport(GRAREG, 0x0005);
	outport(GRAREG, 0xff08);
}


/***************************************************************\
*			cleartext				*
* description : 清图形屏					*
*								*
*								*
\***************************************************************/

void cleargraph(INT8 color)
{
	outport(SEQREG, 0x010e);	// 图形第1段
	outport(SEQREG, 0x0404);	// 位平面方式
	outport(GRAREG, (color<<8)+0);// 将指定颜色装入设置/重置寄存器
	outport(GRAREG, 0x0f01); 	// 允许设置/重置4个位面
	outport(GRAREG, 0xff08);	// 不用锁存器值
	asm{
		mov ax, 0xa000
		mov es, ax
		mov cx, 0xc000
		mov al, 0
		mov di, 0
		rep stosb
	}
	outport(GRAREG, 0x0f00);
	outport(GRAREG, 0x0001);
	outport(SEQREG, 0x0804);
}
/*
static void resetmode(INT8U mode)
{
	INT16U *p, *p1;
	INT16U cnt, cnt1, i, val;
	
	disable();		// 关中断
	switch(mode)
	{
		case 0:		// 24点阵,80列
			p = (INT16U *)recrt24;
			p1 = (INT16U *)reseq24;
			cnt = sizeof(recrt24);
			cnt1 = sizeof(reseq24);
		 	break;
		case 1:		// 16点阵,132列
			p = (INT16U *)recrt16132;
			p1 = (INT16U *)reseq16132;
			cnt = sizeof(recrt16132);
			cnt1= sizeof(reseq16132);
			break;
		case 2:		// 16点阵, 80列
			p = (INT16U *)recrt1680;
			p1 = (INT16U *)reseq1680;
			cnt = sizeof(recrt1680);
			cnt1= sizeof(reseq1680);
			break;
		default:	// 其他为非法模式
			return;
	}
	for(i=0;i<cnt;i++)				// 初始化CRT寄存器
	{
		val = *p++;		
		outport(CRTREG, val);
	}
	for(i=0;i<cnt1;i++)				// 初始化定序器
	{
		val = *p1++;
		outport(SEQREG, val);
	}
	enable();		// 开中断
}
*/

/*******************************************************\
*		RefreshWindow				*
* description :	refresh line table			*
* argument    : lta---------行表结构访问指针		*
*							*
\*******************************************************/
void RefreshWindow(INT8U firstrow, INT8U endrow)
{
	INT16U i;
	INT32U *ltp;
	
	outport(SEQREG, 0x0f0e);
	ltp = MK_FP(0xa000, 0xfe00+4*(firstrow-1));
	for(i=firstrow-1;i<=endrow;i++){
		*ltp++ = linetab[i];
	}
}
/***************************************************************\
*			openscreen				*
* Description : open screen such as text screen, graphics screen*
*               and text and graphics screen			*
*								*
* Arguments   : screen						*
*               0(CLOSESCREEN)------------close screen		*
*		1(OPENSCREEN)------------open screens		*
*               2(OPENTEXTSCR)------------open text screen	*
*               3(OPENGRASCR)------------open graph screen	*
*               4(CLOSETEXTSCR)------------close text screen	*
* 		5(CLOSEGRASCR)------------close graph screen	*
* 								*
\***************************************************************/
void openscreen(int screen)
{	
	switch(screen)
	{
		case CLOSESCREEN:
		case CLOSETEXTSCR:
			closetextscr();
			if(screen==CLOSETEXTSCR)
				break;
		case CLOSEGRASCR:
			closegrascr();
			break;
			
		case OPENSCREEN:
		case OPENTEXTSCR:
			opentextscr();
			if(screen==OPENTEXTSCR)
				break;
		case OPENGRASCR:
			opengrascr();
			break;
		default:
			break;
	}
}

void opentextscr(void)
{
	char val;
	
	outportb(SEQREG, 5);
	val = inportb(SEQREG+1);
	val |= 0x10;
	outport(SEQREG, (val<<8)+5);
}

void opengrascr(void)
{
	char val;
	
	outportb(SEQREG, 1);
	val = inportb(SEQREG+1);
	val &= 0xdf;
	outport(SEQREG, (val<<8)+1);
}
void closetextscr(void)
{
	char val;
	
	outportb(SEQREG, 5);
	val = inportb(SEQREG+1);
	val &= 0xef;
	outport(SEQREG, (val<<8)+5);
}
void closegrascr(void)
{
	char val;
	
	outportb(SEQREG, 1);
	val = inportb(SEQREG+1);
	val |= 0x20;
	outport(SEQREG, (val<<8)+1);
}

/***********************************************************************\
*			HwCursor					*
*									*
\***********************************************************************/

void Cursor(void)
{
	INT16U pos, x, y;
	
	x = win.wincurx + win.winleft - 1;
	y = win.wincury + win.wintop - 1;
	pos = (INT16U)linetab[y-1] + x-1;
	outport(CRTREG, (pos&0xff00)+0x0e);
	outport(CRTREG, (pos<<8)+0x0f);
}



void setlinetab(void)
{
	int i;
	INT16U pos;
	
	pos = (TEXTSEG-12)<<14;
	pos += 8;
	for(i=0;i<32;i++){
		linetab[i] = pos;
		pos += MAXROWBYTES;
	}
	RefreshWindow(1, 32);
}

void OpenCursor(INT8U crs)
{
	INT8U v;
	
	outportb(CRTREG, 0xa);
	v = inportb(CRTREG+1);
	if(crs)
		v &= 0xdf;
	else
		v |= 0x20;
	outport(CRTREG, (v<<8)+0xa);
}

void xwindow(void)
{
	xwin.left = 0;
	xwin.top = 0;
	xwin.right = 639;
	xwin.bottom = 467;
	xwin.mcurx = 320;
	xwin.mcury = 220;
	xwin.oldmcurx = 320;
	xwin.oldmcury = 220;
	xwin.crsp = &ArrorCur;
	xwin.oldcrsp = &ArrorCur;
	GraCursor(xwin.mcurx, xwin.mcury, xwin.crsp);
	mouse.visible = 1; 				// 光标使能
}

void InitVGA(void)
{
	union REGS reg;
	
	reg.x.ax = 0x0002;		// 初始化VGA寄存器,显示模式16点阵80列
	int86(0x10, &reg, &reg);
	reg.h.ah = 1;			// 光标初始化
	int86(0x10, &reg, &reg);
	OpenCursor(1);
	openscreen(OPENSCREEN);
	graphup(1);			// 图形优先
	textbackground(BLACK);
	textcolor(LIGHTGREEN);
	gotoxy(1, 1);
}

⌨️ 快捷键说明

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