📄 ps2port.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
*/
#include <windows.h>
#include <ceddk.h>
#include "ps2port.hpp"
#include "ps2mouse.hpp"
#include "ps2keybd.hpp"
#include <nkintr.h>
#include <oalintr.h>
#include <hwdefs.h>
#include <haluser.h>
void DelayInuSec(DWORD uS);
#define udelay DelayInuSec
// Commands sent to the keyboard.
//
static const UINT8 cmdKeybdReset = 0xFF;
static const UINT8 cmdKeybdLights = 0xED;
//
// Commands sent to the mouse.
//
static const UINT8 cmdMouseReadId = 0xF2;
static const UINT8 cmdMouseSetReportRate = 0xF3;
static const UINT8 cmdMouseEnable = 0xF4;
//
// Mouse and Keyboard Response
//
static const UINT8 response8042Ack = 0xFA;
static const UINT8 response8042Resend = 0xFE;
static const UINT8 response8042IntelliMouseId = 0x03;
/*++
Ps2Port::
KeyboardInterfaceTest:
Writes the keyboard interface test command to the 8042 command register
and reads the response.
Returns true if the success response is read.
--*/
BOOL
Ps2Port::
KeyboardInterfaceTest(
void
)
{
BOOL bRet = false;
bRet = true;
return bRet;
}
/*++
Ps2Port::
KeyboardCommandPut:
Writes a command to the keyboard and reads the response.
Returns true if the success response code is read.
--*/
BOOL
Ps2Port::
KeyboardCommandPut(
UINT8 ui8Cmd
)
{
BOOL bRet = false;
UINT8 ui8Data;
int iTries = 0;
EnterCriticalSection(&m_csWrite);
while( iTries++ < 3 ){
WritePort(ui8Cmd);
if( !ReadPort(&ui8Data) ){
break;
}
if( ui8Data == response8042Ack ){
bRet = true;
break;
}
// resend command if keyboard microcontroller asked for a resend
// otherwise break and return false
if( ui8Data != response8042Resend ) {
ASSERT(0);
break;
}
}
LeaveCriticalSection(&m_csWrite);
return bRet;
}
/*++
Ps2Port::
KeyboardReset:
Sends the keyboard reset command to the keyboard and reads the response.
Returns true if the success response is read.
--*/
BOOL
Ps2Port::
KeyboardReset(
void
)
{
BOOL bRet = false;
UINT8 ui8Data;
EnterCriticalSection(&m_csWrite);
if ( !KeyboardCommandPut(cmdKeybdReset) )
{
goto leave;
}
if ( !ReadPort(&ui8Data) )
{
goto leave;
}
if ( ui8Data != 0xAA )
{
ASSERT(0);
goto leave;
}
bRet = true;
leave:
LeaveCriticalSection(&m_csWrite);
return bRet;
}
/*++
Ps2Port::
KeyboardLights:
Sets the keyboard indicator lights.
--*/
void
Ps2Port::
KeyboardLights(
unsigned int fLights
)
{
// unsigned char ucLEDparity=0,ucNumber;
EnterCriticalSection(&m_csWrite);
WritePort( cmdKeybdLights );
Sleep(4);
WritePort( fLights );
Sleep(4);
LeaveCriticalSection(&m_csWrite);
}
BOOL
Ps2Port::
MouseTest(
void
)
{
BOOL bRet = false;
UINT8 ui8Data;
EnterCriticalSection(&m_csWrite);
m_bIntelliMouseFound=0;
WritePort(cmdMouseReadId);
//ui8Data should contain response8042Ack
if ( !ReadPort(&ui8Data) ) {
goto leave;
}
//ui8Data should contain mouse ID
if ( !ReadPort(&ui8Data) ) {
goto leave;
}
bRet = true;
SetModeIntelliMouse();
if( response8042IntelliMouseId == MouseId() ) {
RETAILMSG(1,(TEXT("****IntelliMouseId mouse***\r\n")));
m_bIntelliMouseFound = true;
}
leave:
LeaveCriticalSection(&m_csWrite);
if ( !bRet )
RETAILMSG(1,(TEXT("MouseTest fails. Mouse probably not present.\r\n")));
return bRet;
}
/*++
Ps2Port::
SetModeIntelliMouse:
Set mouse to IntelliMouse mode. If an IntelliMouse is present:
1. mouse ID becomes response8042IntelliMouseId
2. the motion report format changes
If IntelliMouse not present the mouse ID and motion report format remain at the default values
--*/
void
Ps2Port::
SetModeIntelliMouse(
void
)
{
EnterCriticalSection(&m_csWrite);
// IntelliMouse(R) is uniquely identified by issuing the specific series of Set Report Rate commands:
// 200Hz (0xC8), then 100Hz (0x64), then 80Hz (0x50). The Set Report Rate commands are valid and we
// therefore have to set the report rate back to the default 100Hz (this is done be MouseId() ).
WritePort(cmdMouseSetReportRate);
WritePort(0xC8);
WritePort(cmdMouseSetReportRate);
WritePort(0x64);
WritePort(cmdMouseSetReportRate);
WritePort(0x50);
LeaveCriticalSection(&m_csWrite);
}
UINT8 Ps2Port::MouseId(void )
{
UINT8 ui8MouseId=0;
EnterCriticalSection(&m_csWrite);
WritePort(cmdMouseReadId);
ReadPort(&ui8MouseId);
ASSERT(ui8MouseId == response8042Ack);
ReadPort(&ui8MouseId);
// Set the report rate back to the default 100Hz
WritePort(cmdMouseSetReportRate);
WritePort(0x64);
LeaveCriticalSection(&m_csWrite);
return ui8MouseId;
}
BOOL Ps2Port::ReadPort( PUCHAR pui8Data )
{
return KernelIoControl( IOCTL_HAL_PS2_GET, NULL, 0, pui8Data, 1, NULL);
}
BOOL Ps2Port::MouseDataRead( UINT8 *pui8Data )
{
return ReadPort( pui8Data);
}
BOOL Ps2Port::KeybdDataRead( UINT8 *pui8Data )
{
return ReadPort( pui8Data);
}
void Ps2Port::WritePort( UINT8 data )
{
int iTry=0;
for( iTry=0; iTry<5; iTry ++ )
{
if( KernelIoControl( IOCTL_HAL_PS2_SEND, &data, 1, NULL, 0, NULL) )
break;
RETAILMSG(1, (TEXT("PS2 write failed %d\r\n "),iTry) );
Sleep(1 );
}
}
BOOL Ps2Port::bIntelliMouseFound( void )
{
return m_bIntelliMouseFound;
}
BOOL
Ps2Port::
Initialize(
unsigned int iopBase
)
{
BOOL bRet = false;
RETAILMSG(ZONE_TEST, (TEXT(" PS2 port init %x---%x\r\n "), this,iopBase) );
InitializeCriticalSection(&m_csWrite);
m_bIntelliMouseFound = false;
m_fEnableWake = FALSE;
m_hDevEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
if( !m_hDevEvent )
goto leave;
if ( !InterruptInitialize(SYSINTR_PS2_PORT, m_hDevEvent, NULL, 0) ){
RETAILMSG(ZONE_ERROR, (TEXT(" PS2 port Init interrupt failed \r\n ")) );
goto leave;
}
bRet = true;
leave:
return bRet;
}
void Ps2Port::InterruptDone( void )
{
::InterruptDone( SYSINTR_PS2_PORT);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -