📄 ps2proto.c
字号:
// ps2proto.c
#include <io.h>
#include "ps2proto.h"
#include "uart.h"
#include "delay.h"
#include "ps2protomaps.h"
u08 lastSentByte;
u08 ReceiveError;
u08 PS2_SendByte( u08 abyte, u08 badParity );
u08 PS2_SendBit( u08 abit );
u08 PS2_SendHalfBit( u08 linesOut );
u08 PS2_ReceiveByte( void );
u08 PS2_ReceiveBit( void );
u08 PS2_SendScan( u08 out );
void PS2_SendScanLong( u08 *out );
void PS2_SendScanByte( u08 out );
void PS2_Init( void )
{
outp(0x00, KDDR);
outp(0x0f, KPORT);
while ((inp(KPIN)&(KCLOCKIN|KDATAIN))!=(KCLOCKIN|KDATAIN))
asm("nop");
outp( BV(KbitDATAOUT) | BV(KbitCLOCKOUT), KDDR);
cbi(KPORT, KbitDATAIN);
cbi(KPORT, KbitCLOCKIN);
PS2_SendByte(0xAA,FALSE);
PRINT("\n\r! ");
UART_PrintfProgStr(macro1);
PRINT("\n\r");
}
u08 PS2_SendByte( u08 abyte, u08 badParity )
{
u08 i,j,parity,status;
for (i=0;i<8;i++)
{
if ((inp(KPIN)&KCLOCKIN)!=0) break;
DELAY_25us();
}
if ((inp(KPIN)&KCLOCKIN)==0)
{
status = 0xbb; //busy
}
else
{
lastSentByte = abyte;
parity = (badParity)?0:1;
status = PS2_SendBit(0);
if (!status)
{
for (i=0;i<8;i++)
{
if (abyte&1) {parity++;}
status = PS2_SendBit(abyte&1);
if (status)
break;
else
abyte >>= 1;
}
if (!status)
status = PS2_SendBit(parity&1);
if (!status)
status = PS2_SendBit(1);
}
outp(KDATAOUT|KCLOCKOUT,KPORT);
if (!status)
{
i=0;
while((i<4)&&(inp(KPIN)&KCLOCKIN))
{
DELAY_FullClock();
i++;
}
if (i==4)
status=4;
if (!status)
{
i=0;
while((i<100)&&((inp(KPIN)&KCLOCKIN)==0))
{
j=0;
while((j<4)&&((inp(KPIN)&KCLOCKIN)==0))
{
DELAY_25us();
j++;
}
i++;
}
if (i==100)
status=100;
}
}
}
return status;
}
u08 PS2_SendBit( u08 abit )
{
u08 dataNoClock, dataWithClock, result;
dataNoClock = (abit)?KDATAOUT:0;
dataWithClock = dataNoClock|KCLOCKOUT;
result = PS2_SendHalfBit(dataWithClock);
if (!result)
result = PS2_SendHalfBit(dataNoClock);
return result;
}
u08 PS2_SendHalfBit( u08 linesOut )
{
u08 linesIn;
outp(linesOut,KPORT);
DELAY_FullClock();
linesIn = (inp(KPIN)>>1)&linesOut; // here's that 1 bit higher assumption
if (linesIn != linesOut)
return 2;
else
return 0;
}
u08 PS2_ReceiveByte( void )
{
u08 i,dataIn,parityCalc,parityIn;
ReceiveError=0;
dataIn = 0;
if (((inp(KPIN)&(KDATAIN))==KDATAIN))
{
ReceiveError = 0xaa; // host not sending
}
else
{
parityCalc = 1;
outp(KDATAOUT|KCLOCKOUT,KPORT);
// wait 125us for high
ReceiveError = 3;
for (i=0;i<5;i++)
{
if (inp(KPIN)&KCLOCKIN)
{
ReceiveError = 0;
break;
}
DELAY_25us();
}
// leave high for 1ms
for (i=0;i<3;i++)
DELAY_25us();
outp(KDATAOUT,KPORT);
DELAY_FullClock();
for (i=0;i<8;i++)
{
dataIn>>=1;
if (PS2_ReceiveBit())
{
parityCalc++;
dataIn+=0x80;
}
}
parityIn=(PS2_ReceiveBit())?1:0;
outp(KDATAOUT|KCLOCKOUT,KPORT);
DELAY_HalfClock();
ReceiveError = ((inp(KPIN)&KDATAIN))?0:1;
if (!ReceiveError)
{
outp(KCLOCKOUT,KPORT);
DELAY_HalfClock();
outp(0,KPORT);
DELAY_FullClock();
ReceiveError=(parityIn!=(parityCalc&1))?2:0;
}
outp(KDATAOUT|KCLOCKOUT,KPORT);
}
return dataIn;
}
u08 PS2_ReceiveBit( void )
{
u08 result;
outp(KDATAOUT|KCLOCKOUT,KPORT);
DELAY_HalfClock();
result = ((inp(KPIN)&KDATAIN))?1:0;
DELAY_HalfClock();
outp(KDATAOUT,KPORT);
DELAY_FullClock();
return result;
}
void PS2_Proto( void )
{
u08 data;
data = PS2_ReceiveByte();
if (ReceiveError!=0xaa)
{
if (ReceiveError)
{
PS2_SendByte(0xfe,0);
return;
}
else if (data==0xfe)
PS2_SendByte(lastSentByte,0);
else if (data==0xee)
{
PS2_SendByte(0xee,0);
}
else if (data==0xf2)
{
PS2_SendByte(0xab,0);
PS2_SendByte(0x83,0);
}
else if (data==0xff)
{
PS2_SendByte(0xfa,0);
PS2_SendByte(0xaa,0);
}
else
PS2_SendByte(0xfa,0);
}
}
u08 PS2_SendScan( u08 out )
{
u08 i,j,ScanOut,temp,*macro;
ScanOut = 0;
PRINT("\n\r ss=");
UART_Printfu08(out);
if (out > 0x1f)
{
PRINT(" ");
UART_SendByte(out);
}
if (out> 0xfc)
return 1;
else if (out>= 0xf0)
{
ScanOut = PRG_RDB(&ScanF0s[out-0xF0-1]);
}
else if (out> 0xed)
return 2;
else if (out>= 0xe0)
{
ScanOut = PRG_RDB(&ScanE0s[out-0xE0]);
if ((out< 0xec)||(!out&1))
{
PS2_SendScanByte(0xe0);
PS2_SendScanByte(ScanOut);
}
if ((out< 0xec)||(out&1))
{
PS2_SendScanByte(0xf0);
PS2_SendScanByte(0xe0);
PS2_SendScanByte(ScanOut);
}
return 0;
}
else if (out==0xde)
{
PS2_SendScanLong( ScanPrtScrn );
return 0;
}
else if (out==0xdf)
{
PS2_SendScanLong( ScanPause );
return 0;
}
else if (out> 0xd8)
return 3;
else if (out>= 0xd1)
{
ScanOut = PRG_RDB(&ScanC0s[out-0xC0]);
if (out&1)
{
PS2_SendScanByte(ScanOut);
}
else
{
PS2_SendScanByte(0xf0);
PS2_SendScanByte(ScanOut);
}
return 0;
}
else if (out>= 0xc0)
{
ScanOut = PRG_RDB(&ScanC0s[out-0xC0]);
}
else if (out >= 0xa0)
{
macro = 0;
if (out == 0xa0) {
macro = macro1;
}
if (macro)
{
PRINT("\n\r");
UART_PrintfProgStr(macro);
PRINT("\n\r");
j = 0;
while ( (out=PRG_RDB(¯o[j])) )
{
if ( (temp=PS2_SendScan(out)) )
return temp;
j++;
}
}
return 0;
}
else
{
i = 0;
while ( (temp=PRG_RDB(&asciiToScan[i])) && (temp != out))
i+=2;
if (temp)
ScanOut = PRG_RDB(&asciiToScan[i+1]);
else
return 4;
}
PS2_SendScanByte(ScanOut);
PS2_SendScanByte(0xf0);
PS2_SendScanByte(ScanOut);
return 0;
}
void PS2_SendScanLong( u08 *out )
{
u08 i;
i=0;
while (PRG_RDB(&out[i]))
{
PS2_SendScanByte(PRG_RDB(&out[i]));
i++;
}
}
void PS2_SendScanByte( u08 out )
{
PS2_SendByte(out,FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -