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

📄 keyboard.c

📁 参照MINIX3写的操作系统 用GCC+NASM+BOCHS开发
💻 C
字号:
#include "../include/toyos.h"#include"keyboard.h"

int Pos=50;
PUBLIC void KeyboardHandle()
//键盘中断处理函数,从端口中读取一个字节到扫描码缓冲区中
{      t_8 ScanCode;


	 ScanCode=InByte(KB_DATA);

	if(ScanCodeBuffer.Count<KB_IN_BYTES)
	{
		*(ScanCodeBuffer.Head)=ScanCode;
		ScanCodeBuffer.Head++;
		if(ScanCodeBuffer.Head==ScanCodeBuffer.Buffer+KB_IN_BYTES)
		{
			ScanCodeBuffer.Head=ScanCodeBuffer.Buffer;

				}
	}
	ScanCodeBuffer.Count++;  	
}

PUBLIC void InitKeyboard()
//键盘初始化函数。
{
	//初始化扫描码缓冲区
	ScanCodeBuffer.Count=0;
	ScanCodeBuffer.Head=ScanCodeBuffer.Tail=ScanCodeBuffer.Buffer;	caps_lock	= 0;
	num_lock	= 1;
	scroll_lock	= 0;

	SetLeds();
   //	EnableIrq(0);

}

PUBLIC t_8  GetByteFromScanCode()
//从扫描码缓冲区中读取一个字节
{
	t_8 ScanCode;
	 //	DisableIrq(1);//关中断
	while(ScanCodeBuffer.Count<=0){}
//	asm cli
	ScanCode= *(ScanCodeBuffer.Tail);
	ScanCodeBuffer.Tail++;
	if(ScanCodeBuffer.Tail==ScanCodeBuffer.Buffer+KB_IN_BYTES)
	{
		ScanCodeBuffer.Tail=ScanCodeBuffer.Buffer;

	}
	ScanCodeBuffer.Count--;


	// asm sti //	EnableIrq(1);//开中断

	return ScanCode;
}
PUBLIC void ReadScanCode(TTY *pTTY)
//解析扫描码函数
{    // return ;
	t_8 ScanCode;
	char OutPut[2]={0,0};
	t_bool IsMakeCode;//是MakeCode还是BreakCode
	t_32  Key=0;
	t_32 *KeyRow;

	if(ScanCodeBuffer.Count>0)
 
	{         
		CodeWithE0=FALSE;
		ScanCode= GetByteFromScanCode();

		//处理Pausebreak键
		if(ScanCode==0xE1)
		{
			int i;
			t_8 PausebreakScanCode[]={0xE1,0x1D,0x45,0xE1,0x9D,0xC5};
			t_bool IsPausebreak=TRUE;
			for(i=1;i<6;i++)
			{
				if(GetByteFromScanCode()!=PausebreakScanCode[i])
				{
					IsPausebreak=FALSE;
					break;
				}
			}
			if (IsPausebreak) {
				Key = PAUSEBREAK;
			}
		}//处理PRINTSCREEN键
		else if(ScanCode==0xE0)
		{			CodeWithE0=TRUE;
			ScanCode=GetByteFromScanCode();
			//PRINTSCREEN键按下
			if(ScanCode==0x2A)
			{				CodeWithE0=FALSE;
				if(GetByteFromScanCode()==0xE0)
				{					CodeWithE0=TRUE;
					if(GetByteFromScanCode()==0x37)
					{
						Key=PRINTSCREEN;
						IsMakeCode=TRUE;
					}
				}
			}
			//PRINTSCREEN键弹开
		   if(ScanCode==0xB7)
		   {			CodeWithE0=FALSE;
			if(GetByteFromScanCode()==0xE0)			{				CodeWithE0=FALSE;	
				   if(GetByteFromScanCode()==0xAA)
				   {
					   Key=PRINTSCREEN;
					   IsMakeCode=FALSE;
				   }			}
		   }
		 //非以上特殊按键
		/*if(Key==0)
			CodeWithE0=TRUE;*/
		}
		if (Key!=PAUSEBREAK&&Key!=PRINTSCREEN)
		{
                         //GetByteFromScanCode();

			IsMakeCode=(ScanCode&FLAG_BREAK?FALSE:TRUE);//判断 是MakeCode还是BreakCode
		   	KeyRow=&KeyMap[(ScanCode&0x7F)*MAP_COULMN];//将KeyMap得响应行赋给KeyRow
			Column=0;			t_bool caps = LeftShift||RightShift;			if (caps_lock) {
				if ((KeyRow[0] >= 'a') && (KeyRow[0] <= 'z')){
					caps = !caps;
				}
			}
			if (caps) {
				Column = 1;
			}
			if(CodeWithE0)
			{
				Column=2;
			}

			Key=KeyRow[Column];

			switch(Key)
			{
			case SHIFT_L:
				LeftShift=IsMakeCode;
				break;
			case SHIFT_R:
				RightShift=IsMakeCode;
				break;
			case CTRL_L:
				LeftCtrl=IsMakeCode;
				break;
			case CTRL_R:
				RightCtrl=IsMakeCode;
				break;
			case ALT_L:
				LeftAlt=IsMakeCode;
				break;
			case ALT_R:
				RightAlt=IsMakeCode;
				break;			case CAPS_LOCK:
				if (IsMakeCode) {
					caps_lock   = !caps_lock;
					SetLeds();
				}
				break;
			case NUM_LOCK:
				if (IsMakeCode) {
					num_lock    = !num_lock;
					SetLeds();
				}
				break;
			case SCROLL_LOCK:
				if (IsMakeCode) {
					scroll_lock = !scroll_lock;
					SetLeds();
				}
				break;
			default:
				break;
			}
			//如果是MakeCode则置相应位
			/*if(IsMakeCode)
			{
				Key|=LeftShift ? FLAG_SHIFT_L:0;
				Key|=RightShift ? FLAG_SHIFT_R:0;
				Key|=LeftCtrl ? FLAG_CTRL_L:0;
				Key|=RightCtrl ? FLAG_CTRL_R:0;
				Key|=LeftAlt ? FLAG_ALT_L:0;
				Key|=RightAlt ? FLAG_ALT_R:0;
			
			 InProcess(pTTY,Key);
			}*/


		}		if(IsMakeCode){ /* 忽略 Break Code */
			t_bool pad = FALSE;

			/* 首先处理小键盘 */
			if ((Key >= PAD_SLASH) && (Key <= PAD_9)) {
				pad = TRUE;
				switch(Key) {	/* '/', '*', '-', '+', and 'Enter' in num pad  */
				case PAD_SLASH:
					Key = '/';
					break;
				case PAD_STAR:
					Key = '*';
					break;
				case PAD_MINUS:
					Key = '-';
					break;
				case PAD_PLUS:
					Key = '+';
					break;
				case PAD_ENTER:
					Key = ENTER;
					break;
				default:	/* keys whose value depends on the NumLock */
					if (num_lock) {	/* '0' ~ '9' and '.' in num pad */
						if ((Key >= PAD_0) && (Key <= PAD_9)) {
							Key = Key - PAD_0 + '0';
						}
						else if (Key == PAD_DOT) {
							Key = '.';
						}
					}
					else{
						switch(Key) {
						case PAD_HOME:
							Key = HOME;
							break;
						case PAD_END:
							Key = END;
							break;
						case PAD_PAGEUP:
							Key = PAGEUP;
							break;
						case PAD_PAGEDOWN:
							Key = PAGEDOWN;
							break;
						case PAD_INS:
							Key = INSERT;
							break;
						case PAD_UP:
							Key = UP;
							break;
						case PAD_DOWN:
							Key = DOWN;
							break;
						case PAD_LEFT:
							Key = LEFT;
							break;
						case PAD_RIGHT:
							Key = RIGHT;
							break;
						case PAD_DOT:
							Key = DELETE;
							break;
						default:
							break;
						}
					}
					break;
				}
			}
			Key |= LeftShift	? FLAG_SHIFT_L	: 0;
			Key |= RightShift	? FLAG_SHIFT_R	: 0;
			Key |= LeftCtrl	? FLAG_CTRL_L	: 0;
			Key |= RightCtrl	? FLAG_CTRL_R	: 0;
			Key |= LeftAlt	? FLAG_ALT_L	: 0;
			Key |= RightAlt	? FLAG_ALT_R	: 0;
			Key |= pad	? FLAG_PAD	: 0;

			 InProcess(pTTY,Key);
		}
	}
}
PRIVATE void SetCursor(unsigned int Position)
{
	LockIrq();
	OutByte(CRTC_ADDR_REG,START_CURSOR_H );
	OutByte(CRTC_DATA_REG,(t_8)((Position>>8)&0xFF));
	OutByte(CRTC_ADDR_REG,START_CURSOR_L );
	OutByte(CRTC_DATA_REG,(t_8)(Position&0xFF));
	UnLock();
}
PRIVATE void SetVideoStartAddr(t_32 addr)
{
	LockIrq();
	OutByte(CRTC_ADDR_REG,START_ADDR_H);
	OutByte(CRTC_DATA_REG,(t_8)((addr>>8)&0xFF));
	OutByte(CRTC_ADDR_REG,START_ADDR_L);
	OutByte(CRTC_DATA_REG,(t_8)(addr&0xFF));
	UnLock();
}

PRIVATE void SelectConsole(int nr_Console)
{
	if((nr_Console<0)||(nr_Console>=NR_CONSOLES))
		return ;
	CurrentConsole=nr_Console;
	SetCursor(ConsoleTable[nr_Console].CursorPos);
	SetVideoStartAddr(ConsoleTable[nr_Console].CurrentStartAddr);
}

PUBLIC void ScrollScreen(CONSOLE *pConsole,int Direction)
{
	if(Direction==SCROLL_SCREEN_UP)
	{
		if(pConsole->CurrentStartAddr>pConsole->OriginalAddr)
			pConsole->CurrentStartAddr-=SCREEN_WIDTH;

	}
	else if(Direction==SCROLL_SCREEN_DOWN)
	{
		if(pConsole->CurrentStartAddr+SCREEN_SIZE<
			pConsole->OriginalAddr+pConsole->Size)
			pConsole->CurrentStartAddr+=SCREEN_WIDTH;
	}else
	{
		SetVideoStartAddr(pConsole->CurrentStartAddr);
		SetCursor(pConsole->CursorPos);
	}
}


PUBLIC void OutChar(CONSOLE *pConsole,char ch)
{
	t_8 *p_vmem = (t_8*)(V_MEM_BASE+pConsole->CursorPos*2);	/*	typedef struct s_Console
	{
	unsigned int CurrentStartAddr;
	unsigned int OriginalAddr;
	unsigned int Size;
	unsigned int CursorPos;
	}CONSOLE;
	*p_vmem++ =ch;
	*p_vmem++ =DEFAULT_CHAR_COLOR;
	pConsole->CursorPos++;
	SetCursor(pConsole->CursorPos);*/
		switch(ch) {
	case '\n':
		if (pConsole->CursorPos < pConsole->OriginalAddr + pConsole->Size - SCREEN_WIDTH) {
			pConsole->CursorPos = pConsole->OriginalAddr + SCREEN_WIDTH * ((pConsole->CursorPos - pConsole->OriginalAddr) / SCREEN_WIDTH + 1);
		}
		break;
	case '\b':
		if (pConsole->CursorPos > pConsole->OriginalAddr) {
			pConsole->CursorPos--;
			*(p_vmem-2) = ' ';
			*(p_vmem-1) = DEFAULT_CHAR_COLOR;
		}
		break;
	default:
		if (pConsole->CursorPos <pConsole->OriginalAddr +pConsole->Size - 1) {
			*p_vmem++ = ch;
			*p_vmem++ = DEFAULT_CHAR_COLOR;
			pConsole->CursorPos++;
		}
		break;
	}

	SetCursor(pConsole->CursorPos);
}

PUBLIC void InProcess(TTY *pTTY,t_32 Key)
{
//对按键的处理

	int RawCode=Key&MASK_RAW;
	char OutPut[2]={'\0','\0'};
	if(!(Key&FLAG_EXT))//过滤不可打印字符
	{

		/*if(pTTY->Count<TTY_IN_BYTES)
		{
			*(pTTY->Head)=Key;
			pTTY->Head++;
			if(pTTY->Head==pTTY->Buffer+TTY_IN_BYTES)
				pTTY->Head=pTTY->Buffer;
			pTTY->Count++;	
	
		}*/
		PutKey(pTTY,Key);
	}
	else
	{
	
	
		switch(RawCode)
		{		case ENTER:
			PutKey(pTTY, '\n');
			break;
		case BACKSPACE:
			PutKey(pTTY, '\b');
			break;
		case F5:
		//	if((Key&FLAG_SHIFT_L)||(Key&FLAG_SHIFT_R))
				ScrollScreen(pTTY->pConsole,SCROLL_SCREEN_UP);
			break;
		case F6:
		//	if((Key&FLAG_SHIFT_L)||(Key&FLAG_SHIFT_R))
				ScrollScreen(pTTY->pConsole,SCROLL_SCREEN_DOWN);
			break;
	
		case F1: //Send.Type=1;Send.Next=NULL;goto Lable;
		case F2:// Send.Type=2;Send.Next=NULL;goto Lable;
		case F3:
		case F4:
//Lable:	
			if((Key&FLAG_ALT_L)||(Key&FLAG_ALT_R))
				SelectConsole(RawCode-F1);
			else
			{
				printk("Send IS");
			//	SendMessage( IS,&Send);
			}

			break;
		default :
			break;
		}
	}

}

PUBLIC void InitScreen(TTY *pTTY)
{
	int v_mem_size=V_MEM_SIZE>>1;
	int con_v_mem_size=v_mem_size/NR_CONSOLES;
	int nr_tty=pTTY-TTYTable;
	pTTY->pConsole=ConsoleTable+nr_tty;
	pTTY->pConsole->OriginalAddr=nr_tty*con_v_mem_size;
	pTTY->pConsole->Size=con_v_mem_size;
	pTTY->pConsole->CurrentStartAddr=
		pTTY->pConsole->OriginalAddr;
	pTTY->pConsole->CursorPos=pTTY->pConsole->OriginalAddr;
	if(nr_tty==0)
		pTTY->pConsole->CursorPos=Disp_pos/2;
	else
	{
		OutChar(pTTY->pConsole,(char)(nr_tty+'0'));
		OutChar(pTTY->pConsole,'@');
	}
	SetCursor(pTTY->pConsole->CursorPos);
	
}

PRIVATE void InitTTY(TTY *pTTY)
{
	pTTY->Count=0;
	pTTY->Head=pTTY->Tail=pTTY->Buffer;
	pTTY->pConsole=ConsoleTable+(pTTY-TTYTable);
	pTTY->KeyCount=0;
	pTTY->KeyHead=pTTY->KeyTail=pTTY->KeyBuffer;

	InitScreen(pTTY);
}
PUBLIC t_bool IsCurrentConsole(CONSOLE *pConsole)
{
	return (pConsole==&ConsoleTable[CurrentConsole]);
	
}
PRIVATE void TTYRead(TTY *pTTY)
{

	if(IsCurrentConsole(pTTY->pConsole))
	{

		ReadScanCode(pTTY);
	}
}
PRIVATE void TTYWrite(TTY *pTTY)
{			char ch;
	if(pTTY->Count)
	{
		ch=*(pTTY->Tail);
		pTTY->Tail++;
		if(pTTY->Tail==pTTY->Buffer+TTY_IN_BYTES)
			pTTY->Tail=pTTY->Buffer;
		pTTY->Count--;
	
	OutChar(pTTY->pConsole,ch);
	}

}



PUBLIC void sysTTYWrite(TTY *pTTY,char *buf,int len)
{
	char *p=buf;
	int i=len;
	while(i)
	{
		OutChar(pTTY->pConsole,*p++);
		i--;
	}
}

PUBLIC int sysWrite(char *buf,int len,int console)/* ***************************** edit by et*************************** */
{

	int Console=pCurrentProc->TTYNum;
    if(Console>=NR_CONSOLES)
		Console--;
	if(Console<0)
		Console=0;
	sysTTYWrite(&TTYTable[Console],buf,len);
	return 0;

}

PUBLIC char sysGetChar()
{   
	TTY *pTTY=&TTYTable[0];
	char ch;
	if(pTTY->KeyCount<=0) 
		waitEvent(EV_KEYPRESS);
	if(pTTY->KeyCount>0)
	{
		ch=*(pTTY->KeyTail);
		pTTY->KeyTail++;
		if(pTTY->KeyTail==pTTY->KeyBuffer+TTY_IN_BYTES)
			pTTY->KeyTail=pTTY->KeyBuffer;
		pTTY->KeyCount--;
		OutChar(pTTY->pConsole,ch);
		return ch;
	}
	return '\0';


}
/*
PUBLIC void sysSetCursor(Message *pMess)
{
	int Position=pMess->POSITION;
	TTYTable[0].pConsole->CursorPos=Position;
	SetCursor(Position);

}
PUBLIC char sysGetChar()
{   
	TTY *pTTY=&TTYTable[0];
	char ch;
//	while(pTTY->KeyCount<=0) {}
	if(pTTY->KeyCount>0)
	{
		ch=*(pTTY->KeyTail);
		pTTY->KeyTail++;
		if(pTTY->KeyTail==pTTY->KeyBuffer+TTY_IN_BYTES)
			pTTY->KeyTail=pTTY->KeyBuffer;
		pTTY->KeyCount--;
		return ch;
	}
	return '\0';


}


*/
PUBLIC void initTTY()
{
	TTY *pTTY;
    printk("*************Init TTY****************\n");
	InitKeyboard();
    for(pTTY=TTY_FIRST;pTTY<TTY_END;pTTY++)
		InitTTY(pTTY);
	CurrentConsole=0;
	pTTY=TTY_FIRST;
}
 PUBLIC void keyboardHandler(int Irq)
 {
	TTY *pTTY;
	KeyboardHandle() ;

	for(pTTY=TTY_FIRST;pTTY<TTY_END;pTTY++)
		{  
			 TTYRead(pTTY);
			//	TTYWrite(pTTY);
										
		}
	wakeUpEvent(EV_KEYPRESS);
 }

PRIVATE void SetLeds()
{
	t_8 leds = (caps_lock << 2) | (num_lock << 1) | scroll_lock;

	KbWait();
	OutByte(KB_DATA, LED_CODE);
	KbAck();

	KbWait();
	OutByte(KB_DATA, leds);
	KbAck();
}
PRIVATE void KbWait()	/* 等待 8042 的输入缓冲区空 */
{
	t_8 kb_stat;

	do {
		kb_stat = InByte(KB_CMD);
	} while (kb_stat & 0x02);
}


PRIVATE void KbAck()
{
	t_8 kb_read;

	do {
		kb_read = InByte(KB_DATA);
	} while (kb_read =! KB_ACK);
}
PRIVATE void PutKey(TTY* pTTY, t_32 Key){	if(pTTY->KeyCount<TTY_IN_BYTES)
		{
			*(pTTY->KeyHead)=Key;
			pTTY->KeyHead++;
			if(pTTY->KeyHead==pTTY->KeyBuffer+TTY_IN_BYTES)
				pTTY->KeyHead=pTTY->KeyBuffer;
			pTTY->KeyCount++;	
		}	}




⌨️ 快捷键说明

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