📄 keyb.c
字号:
// keyb.c
#include <io.h>
#include "keyb.h"
#include "uart.h"
#include "delay.h"
#include "ps2proto.h"
#include "keybmaps.h"
volatile extern u08 Timer, TimerType;
u08 KeysToSend, FrontReleasing, SentCombo,
CountFrontKeys,
CountALT, CountCTR, CountSHF, CountNUM,
ThumbSent, ThumbLast, ThumbLock;
u08 RowDebounce[4], RowNew[4], RowSave[4];
u08 KEYB_DoLookup( void );
extern u08 KEYB_LookupSingles( void );
extern u08 KEYB_LookupCombos( void );
void KEYB_Process1ControlKey_Immediate(u08 *count, u08 bitmask, u08 key);
void KEYB_Process1ControlKey_SaveLock(u08 bitmask, u08 key, u08 isBefore);
void KEYB_ControlKeySend(u08 tosend, u08 key);
void KEYB_ShowKeyChanges( void );
void KEYB_Init( void )
{
outp(0x00, DDRROWS);
outp(0x00, PORTROWS);
outp(0x00, DDRCOLS);
outp(0x00, PORTCOLS);
KeysToSend = FALSE;
FrontReleasing = FALSE;
SentCombo = FALSE;
Timer = 0;
TimerType = ttNONE;
CountFrontKeys = 0;
CountALT = 0;
CountCTR = 0;
CountSHF = 0;
CountNUM = 0;
ThumbSent = 0;
ThumbLock = 0;
ThumbLast = 0;
RowSave[THUMBrow] = 0;
}
u08 KEYB_DebounceKeyboard( void )
{
u08 i, j;
#define READ_DELAY 4
RowNew[Qrow] = 0;
RowNew[Arow] = 0;
RowNew[Zrow] = 0;
for (i=1; i<0x40; i<<=1)
{
outp(i,DDRCOLS);
outp(i,PORTCOLS);
for (j=0;j<READ_DELAY;j++)
asm("nop");
if (bit_is_set(PINROWS, BITrowQ))
RowNew[Qrow] |= i;
if (bit_is_set(PINROWS, BITrowA))
RowNew[Arow] |= i;
if (bit_is_set(PINROWS, BITrowZ))
RowNew[Zrow] |= i;
}
outp(0x40,DDRCOLS);
outp(0x40,PORTCOLS);
for (j=0;j<READ_DELAY;j++)
asm("nop");
RowNew[THUMBrow] = (inp(PINROWS)&0x70)>>BITrowQ<<3;
// UART_Printfu08(inp(PINROWS)&0x70); //diag
outp(0x80,DDRCOLS);
outp(0x80,PORTCOLS);
for (j=0;j<READ_DELAY;j++)
asm("nop");
RowNew[THUMBrow] |= (inp(PINROWS)&0x70)>>BITrowQ;
// UART_Printfu08(inp(PINROWS)&0x70); //diag
outp(0,DDRCOLS);
outp(0,PORTCOLS);
if (( RowDebounce[Qrow] != RowNew[Qrow] )
|| (RowDebounce[Arow] != RowNew[Arow])
|| (RowDebounce[Zrow] != RowNew[Zrow])
|| (RowDebounce[THUMBrow] != RowNew[THUMBrow]))
{
RowDebounce[Qrow] = RowNew[Qrow];
RowDebounce[Arow] = RowNew[Arow];
RowDebounce[Zrow] = RowNew[Zrow];
RowDebounce[THUMBrow] = RowNew[THUMBrow];
return 0;
}
else
{
// PRINT("-");
// KEYB_ShowKeyChanges(); // diag
return 1;
}
}
u08 KEYB_GetKeyToSend( void ) // Sees if a front key is ready to send
{
u08 out, i, j, newcount;
out = 0;
newcount = 0;
for (i=0; i<MAX_ROW; i++)
for (j=1; j<=MAX_COL; j<<=1)
if (RowNew[i]&j)
newcount++;
if (CountFrontKeys > newcount)
FrontReleasing = TRUE;
else
FrontReleasing = FALSE;
CountFrontKeys = newcount;
if (FrontReleasing) // don't eval RowSave until new press & release
{
// KEYB_ShowKeyChanges(); // diag
if (KeysToSend)
{
out = KEYB_DoLookup();
}
RowSave[Qrow] = RowNew[Qrow];
RowSave[Arow] = RowNew[Arow];
RowSave[Zrow] = RowNew[Zrow];
if (!CountFrontKeys)
{
Timer = 0;
TimerType = ttNONE;
SentCombo = FALSE;
}
}
else
{
if ((RowSave[Qrow] != RowNew[Qrow])
|| (RowSave[Arow] != RowNew[Arow])
|| (RowSave[Zrow] != RowNew[Zrow]))
{
KEYB_ShowKeyChanges(); // diag
RowSave[Qrow] |= RowNew[Qrow];
RowSave[Arow] |= RowNew[Arow];
RowSave[Zrow] |= RowNew[Zrow];
if (!KeysToSend)
{
KeysToSend = TRUE;
Timer = INTERVAL_INITIAL;
TimerType = ttINITIAL;
}
}
else
if ((TimerType!=ttNONE)&&(!Timer))
{
if (TimerType==ttINITIAL)
Timer = INTERVAL_PREREPEAT;
else
Timer = INTERVAL_REPEAT;
TimerType = ttPREREPEAT;
out = KEYB_DoLookup();
}
}
if (!CountFrontKeys)
{
RowSave[THUMBrow] &= ~(FLPbit|FNCbit);
RowSave[THUMBrow] |= RowNew[THUMBrow]&(FLPbit|FNCbit);
}
return out;
}
u08 KEYB_DoLookup( void )
{
u08 i,j,out,count;
out=0;
count=0;
for (i=0;i<MAX_ROW;i++)
for (j=1;j<=MAX_COL;j<<=1)
if (RowSave[i]&j)
count++;
if ((count==1)&&(!SentCombo))
{
out = KEYB_LookupSingles();
}
if (count>1)
{
out = KEYB_LookupCombos();
SentCombo = TRUE;
}
KeysToSend = FALSE;
return out;
}
u08 KEYB_LookupSingles( void )
{
u08 *singlemap, i, j;
if (FNCbit & RowSave[THUMBrow])
singlemap = FNMap;
else
if ((NUMbit & RowSave[THUMBrow])&&(NUMbit & ~ThumbLock))
singlemap = NumMap;
else
if ((NUMbit & ~RowSave[THUMBrow])&&(NUMbit & ThumbLock))
singlemap = NumMap;
else
if (FLPbit & RowSave[THUMBrow])
singlemap = FlipMap;
else
singlemap = StdMap;
for (i=0;i<MAX_ROW;i++)
for (j=1;j<=MAX_COL;j<<=1)
{
if (RowSave[i]&j)
{
return PRG_RDB(singlemap);
break;
}
singlemap++;
}
return 0;
}
u08 KEYB_LookupCombos( void )
{
u08 *currChord;
if (FNCbit & RowSave[THUMBrow])
currChord = FNChordMap;
else
currChord = ChordMap;
while (PRG_RDB(&currChord[0]) != MAPEND)
{
if ( (RowSave[0] == PRG_RDB(&currChord[0]))
&& (RowSave[1] == PRG_RDB(&currChord[1]))
&& (RowSave[2] == PRG_RDB(&currChord[2])) )
return PRG_RDB(&currChord[3]);
currChord += 4;
}
return 0;
}
void KEYB_ShowKeyChanges( void )
{
PRINT("\n\r0=");
UART_Printfu08(RowNew[0]);
PRINT(" 1=");
UART_Printfu08(RowNew[1]);
PRINT(" 2=");
UART_Printfu08(RowNew[2]);
PRINT(" 3=");
UART_Printfu08(RowNew[3]);
}
void KEYB_ProcessControlKeys_Immediate( void )
{
#ifdef debug_NACS
printf(" rs.%2.2hx tk.%2.2hx ts.%2.2hx ",
RowSave[THUMBrow],ThumbLock,ThumbSent);
#endif
KEYB_Process1ControlKey_Immediate(&CountALT,ALTbit,0xd5);
KEYB_Process1ControlKey_Immediate(&CountCTR,CTRbit,0xd3);
KEYB_Process1ControlKey_Immediate(&CountSHF,SHFbit,0xd1);
KEYB_Process1ControlKey_Immediate(&CountNUM,NUMbit,0);
ThumbLast = RowNew[THUMBrow];
}
// handles single control key
void KEYB_Process1ControlKey_Immediate(u08 *count, u08 bitmask, u08 key)
{
u08 tosend;
// count state changes
if (*count&1) // count is 1 or 3
{
if (bitmask&~RowNew[THUMBrow])
if (bitmask&ThumbLast)
*count = (*count)+1;
}
else
{
if (bitmask&RowNew[THUMBrow])
if (bitmask&~ThumbLast)
*count = (*count)+1;
}
if (*count>0)
RowSave[THUMBrow] |= RowNew[THUMBrow]&bitmask;
else
RowSave[THUMBrow] &= ~(bitmask&~RowNew[THUMBrow]);
// toggles key lock
if (*count>3)
{
*count = 0;
ThumbLock ^= bitmask;
RowSave[THUMBrow] &= ~bitmask;
return;
}
if (!key) // num: don't need to send anything
return;
tosend = (bitmask&RowNew[THUMBrow])^(bitmask&ThumbLock);
if (tosend==(ThumbSent&bitmask))
return;
KEYB_ControlKeySend(tosend, key);
// store key sent
if (tosend)
ThumbSent |= bitmask;
else
ThumbSent &= ~bitmask;
}
void KEYB_ProcessControlKeys_SaveLock( u08 isBefore )
{
KEYB_Process1ControlKey_SaveLock(ALTbit,0xd5, isBefore);
KEYB_Process1ControlKey_SaveLock(CTRbit,0xd3, isBefore);
KEYB_Process1ControlKey_SaveLock(SHFbit,0xd1, isBefore);
if (!isBefore)
{
CountALT = 0;
CountCTR = 0;
CountSHF = 0;
CountNUM = 0;
RowSave[THUMBrow] = RowNew[THUMBrow];
}
}
void KEYB_Process1ControlKey_SaveLock(u08 bitmask, u08 key, u08 isBefore)
{
u08 tosend = 0;
tosend = (bitmask&RowSave[3])^(bitmask&ThumbLock);
if (tosend==(ThumbSent&bitmask))
return;
if (isBefore)
KEYB_ControlKeySend(tosend, key);
else
KEYB_ControlKeySend(!tosend, key);
}
void KEYB_ControlKeySend(u08 tosend, u08 key)
{
if (tosend)
PS2_SendScan( key ); // send press
else
PS2_SendScan( key+1 ); // send release
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -