/*********************************************************************************\
* 显示驱动 *
* *
* 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