Initial (manual) import
This commit is contained in:
1 parent
f39611c506
commit
895fe109de
661 files changed
+245862
No files matched your search
@@ -0,0 +1,492 @@
|
||||
asm {
|
||||
NORMAL_KEY_SCAN_DECODE_TABLE::
|
||||
DU8 0,CH_ESC,"1234567890-=",CH_BACKSPACE,'\t';
|
||||
DU8 "qwertyuiop[]",'\n',0,"as";
|
||||
DU8 "dfghjkl;'\`",0,"\\zxcv";
|
||||
DU8 "bnm,./",0,'*',0,CH_SPACE,0,0,0,0,0,0;
|
||||
DU8 0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
|
||||
SHIFT_KEY_SCAN_DECODE_TABLE::
|
||||
DU8 0,CH_SHIFT_ESC,"!@#$$%^&*()_+",CH_BACKSPACE,'\t';
|
||||
DU8 "QWERTYUIOP{}",'\n',0,"AS";
|
||||
DU8 "DFGHJKL:\"~",0,"|ZXCV";
|
||||
DU8 "BNM<>?",0,'*',0,CH_SHIFT_SPACE,0,0,0,0,0,0;
|
||||
DU8 0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
|
||||
CTRL_KEY_SCAN_DECODE_TABLE::
|
||||
DU8 0,CH_ESC,"1234567890-=",CH_BACKSPACE,'\t';
|
||||
DU8 CH_CTRLQ,CH_CTRLW,CH_CTRLE,CH_CTRLR,CH_CTRLT,CH_CTRLY,CH_CTRLU,
|
||||
CH_CTRLI,CH_CTRLO,CH_CTRLP,"[]",'\n',0,CH_CTRLA,CH_CTRLS;
|
||||
DU8 CH_CTRLD,CH_CTRLF,CH_CTRLG,CH_CTRLH,CH_CTRLJ,CH_CTRLK,CH_CTRLL,
|
||||
";'\`",0,"\\",CH_CTRLZ,CH_CTRLX,CH_CTRLC,CH_CTRLV;
|
||||
DU8 CH_CTRLB,CH_CTRLN,CH_CTRLM,",./",0,'*',0,CH_SPACE,0,0,0,0,0,0;
|
||||
DU8 0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
|
||||
}
|
||||
|
||||
U0 KbdCmdSend(I64 port, U8 val)
|
||||
{
|
||||
F64 timeout=tS+0.125;
|
||||
while (tS<timeout) {
|
||||
if (!(InU8(KBD_CTRL)&2)) {
|
||||
OutU8(port,val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
I64 KbdCmdRead()
|
||||
{
|
||||
F64 timeout=tS+0.125;
|
||||
while (tS<timeout)
|
||||
if (InU8(KBD_CTRL)&1)
|
||||
return InU8(KBD_PORT);
|
||||
throw;
|
||||
}
|
||||
|
||||
U0 KbdCmdFlush()
|
||||
{
|
||||
F64 timeout=tS+0.03;
|
||||
while (tS<timeout)
|
||||
InU8(KBD_PORT);
|
||||
}
|
||||
|
||||
U0 KbdLEDsSet(I64 sc)
|
||||
{
|
||||
U8 v=0;
|
||||
BEqu(&v,0,Bt(&sc,SCf_SCROLL));
|
||||
BEqu(&v,1,Bt(&sc,SCf_NUM));
|
||||
BEqu(&v,2,Bt(&sc,SCf_CAPS));
|
||||
try {
|
||||
KbdCmdSend(KBD_PORT,0xED);
|
||||
KbdCmdSend(KBD_PORT,v);
|
||||
} catch
|
||||
Fs->catch_except=TRUE;
|
||||
}
|
||||
|
||||
U0 KbdMsCmdAck(...)
|
||||
{
|
||||
I64 i,ack,timeout;
|
||||
for (i=0;i<argc;i++) {
|
||||
timeout=5;
|
||||
do {
|
||||
ack=0;
|
||||
try {
|
||||
KbdCmdSend(KBD_CTRL,0xD4);
|
||||
KbdCmdSend(KBD_PORT,argv[i]);
|
||||
ack=KbdCmdRead;
|
||||
} catch {
|
||||
KbdCmdFlush;
|
||||
Fs->catch_except=TRUE;
|
||||
}
|
||||
} while (ack!=0xFA && --timeout);
|
||||
if (!timeout)
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
U0 KbdTypeMatic(U8 delay)
|
||||
{//Set speed of repeated keys.
|
||||
try {
|
||||
KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
|
||||
KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
|
||||
KbdCmdSend(KBD_PORT,0xF3);
|
||||
KbdCmdSend(KBD_PORT,delay); //Typematic rate
|
||||
KbdCmdSend(KBD_CTRL,0xA8); //Enable Mouse
|
||||
} catch {
|
||||
KbdCmdFlush;
|
||||
Fs->catch_except=TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
I64 Char2ScanCode(I64 ch,I64 sc_flags=0)
|
||||
{//ASCII val to scan code (Slow).
|
||||
I64 i;
|
||||
U8 *table;
|
||||
if (sc_flags) {
|
||||
table=NORMAL_KEY_SCAN_DECODE_TABLE;
|
||||
if (sc_flags & SCF_CTRL || ch<26)
|
||||
table=CTRL_KEY_SCAN_DECODE_TABLE;
|
||||
else if (sc_flags & SCF_SHIFT || 'A'<=ch<='Z') {
|
||||
if (!(sc_flags & SCF_CAPS))
|
||||
table=SHIFT_KEY_SCAN_DECODE_TABLE;
|
||||
} else {
|
||||
if (sc_flags & SCF_CAPS)
|
||||
table=SHIFT_KEY_SCAN_DECODE_TABLE;
|
||||
}
|
||||
for (i=0;i<0x50;i++)
|
||||
if (table[i]==ch)
|
||||
return i|sc_flags;
|
||||
return sc_flags;
|
||||
} else {
|
||||
table=NORMAL_KEY_SCAN_DECODE_TABLE;
|
||||
for (i=0;i<0x50;i++)
|
||||
if (table[i]==ch)
|
||||
return i;
|
||||
table=SHIFT_KEY_SCAN_DECODE_TABLE;
|
||||
for (i=0;i<0x50;i++)
|
||||
if (table[i]==ch)
|
||||
return i|SCF_SHIFT;
|
||||
table=CTRL_KEY_SCAN_DECODE_TABLE;
|
||||
for (i=0;i<0x50;i++)
|
||||
if (table[i]==ch)
|
||||
return i|SCF_CTRL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
U8 ScanCode2Char(I64 sc)
|
||||
{//Scan code to ASCII val.
|
||||
U8 *table=NORMAL_KEY_SCAN_DECODE_TABLE;
|
||||
if (sc&SCF_E0_PREFIX)
|
||||
return 0;
|
||||
if (sc&SCF_CTRL)
|
||||
table=CTRL_KEY_SCAN_DECODE_TABLE;
|
||||
else if (sc&SCF_SHIFT) {
|
||||
if (!(sc&SCF_CAPS))
|
||||
table=SHIFT_KEY_SCAN_DECODE_TABLE;
|
||||
} else {
|
||||
if (sc&SCF_CAPS)
|
||||
table=SHIFT_KEY_SCAN_DECODE_TABLE;
|
||||
}
|
||||
sc&=0x7F;
|
||||
if (sc>=0x50)
|
||||
return 0;
|
||||
else
|
||||
return table[sc];
|
||||
}
|
||||
|
||||
U8 scan_code_map[0x100]={
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,SC_SHIFT,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,SC_ENTER,SC_CTRL,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,SC_HOME,
|
||||
SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
|
||||
SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INS,SC_DELETE,0,0,0,0,
|
||||
0,0,0,0,SC_GUI,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
|
||||
U8 num_lock_map[0x100]={
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,8,9,10,0,5,6,7,0,2,
|
||||
3,4,11,0x34,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,SC_ENTER,SC_CTRL,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,SC_HOME,
|
||||
SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
|
||||
SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INS,SC_DELETE,0,0,0,0,
|
||||
0,0,0,0,SC_GUI,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
|
||||
U8 *Char2KeyName(I64 ch,Bool include_ctrl=TRUE)
|
||||
{//ASCII val to key name.
|
||||
I64 i;
|
||||
U8 buf[STR_LEN];
|
||||
if (ch<=CH_SPACE) {
|
||||
switch [ch] {
|
||||
case '\n':
|
||||
StrCpy(buf,"ENTER");
|
||||
break;
|
||||
case CH_BACKSPACE:
|
||||
StrCpy(buf,"BACKSPACE");
|
||||
break;
|
||||
case '\t':
|
||||
StrCpy(buf,"TAB");
|
||||
break;
|
||||
case CH_ESC:
|
||||
StrCpy(buf,"ESC");
|
||||
break;
|
||||
case CH_SHIFT_ESC:
|
||||
StrCpy(buf,"SHIFT_ESC");
|
||||
break;
|
||||
case 0: //nobound switch
|
||||
case 29:
|
||||
case 30:
|
||||
*buf=0;
|
||||
break;
|
||||
case CH_SHIFT_SPACE:
|
||||
StrCpy(buf,"SHIFT_SPACE");
|
||||
break;
|
||||
case CH_SPACE:
|
||||
StrCpy(buf,"SPACE");
|
||||
break;
|
||||
default:
|
||||
if (include_ctrl)
|
||||
StrCpy(buf,"CTRL ");
|
||||
buf[i=StrLen(buf)]=ch-1+'a';
|
||||
buf[i+1]=0;
|
||||
break;
|
||||
}
|
||||
} else if (Bt(char_bmp_printable,ch)) {
|
||||
*buf=ch;
|
||||
buf[1]=0;
|
||||
} else
|
||||
*buf=0;
|
||||
return StrNew(buf);
|
||||
}
|
||||
|
||||
U8 *ScanCode2KeyName(I64 sc)
|
||||
{//Scan code to key name.
|
||||
I64 ch;
|
||||
U8 buf[STR_LEN],*st;
|
||||
*buf=0;
|
||||
if (sc&SCF_CTRL)
|
||||
CatPrint(buf,"CTRL ");
|
||||
if (sc&SCF_ALT)
|
||||
CatPrint(buf,"ALT ");
|
||||
if (sc&SCF_SHIFT)
|
||||
CatPrint(buf,"SHIFT ");
|
||||
if (sc&SCF_NO_SHIFT)
|
||||
CatPrint(buf," ");
|
||||
if (ch=ScanCode2Char(sc&255)) {
|
||||
st=Char2KeyName(ch,FALSE);
|
||||
StrCpy(buf+StrLen(buf),st);
|
||||
Free(st);
|
||||
} else {
|
||||
switch (sc&255) {
|
||||
case SC_BACKSPACE:CatPrint(buf,"BACK"); break;
|
||||
case SC_CAPS: CatPrint(buf,"CAPS"); break;
|
||||
case SC_NUM: CatPrint(buf,"NUM"); break;
|
||||
case SC_SCROLL: CatPrint(buf,"SCROLL"); break;
|
||||
case SC_CURSOR_UP:CatPrint(buf,"UP"); break;
|
||||
case SC_CURSOR_DOWN:CatPrint(buf,"DOWN"); break;
|
||||
case SC_CURSOR_LEFT:CatPrint(buf,"LEFT"); break;
|
||||
case SC_CURSOR_RIGHT:CatPrint(buf,"RIGHT"); break;
|
||||
case SC_PAGE_UP: CatPrint(buf,"PAGE_UP"); break;
|
||||
case SC_PAGE_DOWN:CatPrint(buf,"PAGE_DOWN");break;
|
||||
case SC_HOME: CatPrint(buf,"HOME"); break;
|
||||
case SC_END: CatPrint(buf,"END"); break;
|
||||
case SC_INS: CatPrint(buf,"INS"); break;
|
||||
case SC_DELETE: CatPrint(buf,"DELETE"); break;
|
||||
case SC_F1: CatPrint(buf,"F1"); break;
|
||||
case SC_F2: CatPrint(buf,"F2"); break;
|
||||
case SC_F3: CatPrint(buf,"F3"); break;
|
||||
case SC_F4: CatPrint(buf,"F4"); break;
|
||||
case SC_F5: CatPrint(buf,"F5"); break;
|
||||
case SC_F6: CatPrint(buf,"F6"); break;
|
||||
case SC_F7: CatPrint(buf,"F7"); break;
|
||||
case SC_F8: CatPrint(buf,"F8"); break;
|
||||
case SC_F9: CatPrint(buf,"F9"); break;
|
||||
case SC_F10: CatPrint(buf,"F10"); break;
|
||||
case SC_F11: CatPrint(buf,"F11"); break;
|
||||
case SC_F12: CatPrint(buf,"F12"); break;
|
||||
case SC_GUI: CatPrint(buf,"WINDOWS"); break;
|
||||
case SC_PRTSCRN1: CatPrint(buf,"PRTSCRN1"); break;
|
||||
case SC_PRTSCRN2: CatPrint(buf,"PRTSCRN2"); break;
|
||||
}
|
||||
}
|
||||
return StrNew(buf);
|
||||
}
|
||||
|
||||
U0 KbdBuildSC(U8 raw_byte,Bool in_irq,U8 *_last_raw_byte,I64 *_last_sc)
|
||||
{
|
||||
I64 ch,sc_flags,sc,sc2,sc_raw,new_key_f;
|
||||
Bool set_LEDs=FALSE;
|
||||
if (raw_byte==0xE0) {
|
||||
*_last_sc&=~0x1FF;
|
||||
*_last_raw_byte=raw_byte;
|
||||
return;
|
||||
}
|
||||
sc=raw_byte;
|
||||
BEqu(&sc,SCf_E0_PREFIX,*_last_raw_byte==0xE0);
|
||||
BEqu(&sc,SCf_KEY_UP,raw_byte & 0x80);
|
||||
*_last_raw_byte=raw_byte;
|
||||
|
||||
sc_flags=_last_sc->u32[0]&~0x1FF;
|
||||
sc_raw=sc;
|
||||
|
||||
if (sc_flags & SCF_NUM) {
|
||||
if (sc2=num_lock_map[sc.u8[0]])
|
||||
sc.u8[0]=sc2;
|
||||
} else {
|
||||
if (sc2=scan_code_map[sc.u8[0]])
|
||||
sc.u8[0]=sc2;
|
||||
}
|
||||
|
||||
new_key_f=SCF_NEW_KEY;
|
||||
if (sc&SCF_KEY_UP)
|
||||
switch (sc&~SCF_KEY_UP) {
|
||||
case SC_SHIFT: sc_flags&=~SCF_SHIFT; break;
|
||||
case SC_CTRL: sc_flags&=~SCF_CTRL; break;
|
||||
case SC_ALT: sc_flags&=~SCF_ALT; break;
|
||||
case SC_DELETE: sc_flags&=~SCF_DELETE; break;
|
||||
case SC_INS: sc_flags&=~SCF_INS; break;
|
||||
case SC_CAPS: sc_flags^=SCF_CAPS; set_LEDs=TRUE; break;
|
||||
case SC_NUM: sc_flags^=SCF_NUM; set_LEDs=TRUE; break;
|
||||
case SC_SCROLL: sc_flags^=SCF_SCROLL; set_LEDs=TRUE; break;
|
||||
}
|
||||
else
|
||||
switch (sc) {
|
||||
case SC_SHIFT:
|
||||
if (Bts(&sc_flags,SCf_SHIFT)) new_key_f=0;
|
||||
break;
|
||||
case SC_CTRL:
|
||||
if (Bts(&sc_flags,SCf_CTRL)) new_key_f=0;
|
||||
break;
|
||||
case SC_ALT:
|
||||
if (Bts(&sc_flags,SCf_ALT)) new_key_f=0;
|
||||
break;
|
||||
case SC_DELETE:
|
||||
sc_flags|=SCF_DELETE;
|
||||
break;
|
||||
case SC_INS:
|
||||
sc_flags|=SCF_INS;
|
||||
break;
|
||||
}
|
||||
|
||||
sc_flags|=new_key_f;
|
||||
sc=sc_flags|sc|(sc_flags|sc_raw)<<32;
|
||||
if (sc_flags & SCF_CTRL && sc_flags & SCF_ALT) {
|
||||
if (!(sc&SCF_KEY_UP)) {
|
||||
if (sc&255==SC_DELETE && !(sc_flags & SCF_SHIFT))
|
||||
CtrlAltDel(sc);
|
||||
else {
|
||||
if (sc&255==SC_ESC)
|
||||
ch='t';
|
||||
else if (sc&255==SC_TAB)
|
||||
ch='n';
|
||||
else
|
||||
ch=ScanCode2Char(sc&255);
|
||||
if ('a'<=ch<='z') {
|
||||
sc&=~(SCF_NEW_KEY|SCF_NEW_KEY<<32);
|
||||
ch-='a';
|
||||
kbd.last_down_scan_code=sc;
|
||||
if (keydev.fp_ctrl_alt_cbs[ch] &&
|
||||
Bt(&keydev.ctrl_alt_in_irq_flags,ch)==in_irq &&
|
||||
(!(sc_flags & SCF_SHIFT)&&keydev.ctrl_alt_no_shift_descs[ch]) ||
|
||||
sc_flags & SCF_SHIFT && keydev.ctrl_alt_shift_descs[ch])
|
||||
(*keydev.fp_ctrl_alt_cbs[ch])(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (set_LEDs && !in_irq)
|
||||
KbdLEDsSet(sc);
|
||||
*_last_sc=sc;
|
||||
}
|
||||
|
||||
U0 KbdPktRead()
|
||||
{
|
||||
static U8 last_raw_byte=0;
|
||||
static I64 last_sc=0;
|
||||
U8 raw_byte;
|
||||
if (GetTSC>kbd.timestamp+cnts.time_stamp_freq>>3)
|
||||
FifoU8Flush(kbd.fifo);
|
||||
kbd.timestamp=GetTSC;
|
||||
raw_byte=InU8(KBD_PORT);
|
||||
KbdBuildSC(raw_byte,TRUE,&last_raw_byte,&last_sc);
|
||||
if (!FifoU8Cnt(kbd.fifo)) {
|
||||
FifoU8Ins(kbd.fifo,raw_byte);
|
||||
if (raw_byte!=0xE0) {
|
||||
while (FifoU8Rem(kbd.fifo,&raw_byte))
|
||||
FifoU8Ins(kbd.fifo2,raw_byte);
|
||||
}
|
||||
} else {
|
||||
FifoU8Ins(kbd.fifo,raw_byte);
|
||||
while (FifoU8Rem(kbd.fifo,&raw_byte))
|
||||
FifoU8Ins(kbd.fifo2,raw_byte);
|
||||
}
|
||||
}
|
||||
|
||||
interrupt U0 IRQKbd()
|
||||
{
|
||||
CLD
|
||||
OutU8(0x20,0x20);
|
||||
kbd.irqs_working=TRUE;
|
||||
if (ms_hard.install_in_progress) {
|
||||
kbd.rst=TRUE;
|
||||
return;
|
||||
}
|
||||
keydev.ctrl_alt_ret_addr=GetRBP()(I64)+8;
|
||||
KbdPktRead;
|
||||
}
|
||||
|
||||
U0 KbdInit()
|
||||
{
|
||||
try {
|
||||
KbdCmdFlush;
|
||||
KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
|
||||
KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
|
||||
KbdCmdSend(KBD_PORT,0xF0);
|
||||
KbdCmdSend(KBD_PORT,0x02);
|
||||
KbdLEDsSet(kbd.scan_code);
|
||||
} catch {
|
||||
KbdCmdFlush;
|
||||
Fs->catch_except=TRUE;
|
||||
}
|
||||
IntEntrySet(0x21,&IRQKbd);
|
||||
OutU8(0x21,InU8(0x21)&~2);
|
||||
}
|
||||
|
||||
U0 KbdHndlr()
|
||||
{
|
||||
static U8 last_raw_byte=0;
|
||||
U8 raw_byte;
|
||||
FifoU8Rem(kbd.fifo2,&raw_byte);
|
||||
KbdBuildSC(raw_byte,FALSE,&last_raw_byte,&kbd.scan_code);
|
||||
if (raw_byte==0xE0) {
|
||||
FifoU8Rem(kbd.fifo2,&raw_byte);
|
||||
KbdBuildSC(raw_byte,FALSE,&last_raw_byte,&kbd.scan_code);
|
||||
}
|
||||
if (Btr(&kbd.scan_code,SCf_NEW_KEY)) {
|
||||
kbd.new_key_timestamp=kbd.timestamp;
|
||||
Btr(&kbd.scan_code,32+SCf_NEW_KEY);
|
||||
FifoI64Ins(kbd.scan_code_fifo,kbd.scan_code);
|
||||
kbd.cnt++;
|
||||
if (!(kbd.scan_code&SCF_KEY_UP)) {
|
||||
kbd.last_down_scan_code=kbd.scan_code;
|
||||
Bts(kbd.down_bitmap,kbd.scan_code.u8[0]);
|
||||
Bts(kbd.down_bitmap2,kbd.scan_code.u8[4]);
|
||||
} else {
|
||||
Btr(kbd.down_bitmap,kbd.scan_code.u8[0]);
|
||||
Btr(kbd.down_bitmap2,kbd.scan_code.u8[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
I64 KbdMsgsQue()
|
||||
{
|
||||
I64 arg1,arg2,msg_code=MSG_NULL;
|
||||
CTask *task_focus;
|
||||
if (task_focus=sys_focus_task) {
|
||||
while (FifoI64Rem(kbd.scan_code_fifo,&arg2)) {
|
||||
arg1=ScanCode2Char(arg2);
|
||||
if (arg2 & SCF_KEY_UP) {
|
||||
TaskMsg(task_focus,0,MSG_KEY_UP,arg1,arg2,0);
|
||||
msg_code=MSG_KEY_UP;
|
||||
} else {
|
||||
TaskMsg(task_focus,0,MSG_KEY_DOWN,arg1,arg2,0);
|
||||
msg_code=MSG_KEY_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return msg_code;
|
||||
}
|
||||
|
||||
I64 KbdMsEvtTime()
|
||||
{//Timestamp of last key or mouse event.
|
||||
if (ms_hard.timestamp>kbd.timestamp)
|
||||
return ms_hard.timestamp;
|
||||
else
|
||||
return kbd.new_key_timestamp;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#exe {Cd(__DIR__);};
|
||||
#include "Keyboard"
|
||||
#include "Mouse"
|
||||
#include "Message"
|
||||
#exe {Cd("..");};
|
||||
@@ -0,0 +1,244 @@
|
||||
U0 InputFilterTask()
|
||||
{
|
||||
CJob *tmpc,*tmpc1;
|
||||
Bool old_filter;
|
||||
I64 old_flags=GetRFlags;
|
||||
Fs->win_inhibit=WIG_USER_TASK_DFT;
|
||||
LBts(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
||||
old_filter=LBts(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);
|
||||
LBEqu(&Fs->task_flags,TASKf_FILTER_INPUT,old_filter);
|
||||
while (TRUE) {
|
||||
CLI
|
||||
JobsHndlr(old_flags);
|
||||
tmpc1=&Fs->srv_ctrl.next_waiting;
|
||||
tmpc=tmpc1->next;
|
||||
if (tmpc==tmpc1)
|
||||
break;
|
||||
else {
|
||||
if (tmpc->job_code==JOBT_TEXT_INPUT) {
|
||||
QueRem(tmpc);
|
||||
SetRFlags(old_flags);
|
||||
try
|
||||
ExePrint("%s",tmpc->aux_str);
|
||||
catch
|
||||
Fs->catch_except=TRUE;
|
||||
JobDel(tmpc);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
Fs->next_input_filter_task->last_input_filter_task=Fs->last_input_filter_task;
|
||||
Fs->last_input_filter_task->next_input_filter_task=Fs->next_input_filter_task;
|
||||
if (!old_filter)
|
||||
LBtr(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);
|
||||
SetRFlags(old_flags);
|
||||
}
|
||||
|
||||
I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)
|
||||
{/*Check for a message of type specified by a one in the mask.
|
||||
Throw-out messages not in mask.
|
||||
If no message fit mask, return NULL immediately.
|
||||
Remove desired message, return $LK,"msg_code",A="MN:MSG_CMD"$.
|
||||
Note: This delivers messages from parent down to pop-up.
|
||||
*/
|
||||
I64 res,old_flags;
|
||||
CJob *tmpc,*tmpc1;
|
||||
if (!task) task=Fs;
|
||||
old_flags=GetRFlags;
|
||||
tmpc1=&task->srv_ctrl.next_waiting;
|
||||
while (TRUE) {
|
||||
CLI
|
||||
if (task==Fs)
|
||||
JobsHndlr(old_flags);
|
||||
tmpc=tmpc1->next;
|
||||
if (tmpc==tmpc1)
|
||||
break;
|
||||
else {
|
||||
if (tmpc->job_code==JOBT_MSG) {
|
||||
QueRem(tmpc);
|
||||
SetRFlags(old_flags);
|
||||
res=tmpc->msg_code;
|
||||
if (_arg1)
|
||||
*_arg1=tmpc->aux1;
|
||||
if (_arg2)
|
||||
*_arg2=tmpc->aux2;
|
||||
JobDel(tmpc);
|
||||
if ((res!=MSG_KEY_DOWN || !(tmpc->aux2&SCF_KEY_DESC) ||
|
||||
!Bt(&task->win_inhibit,WIf_SELF_KEY_DESC)) && Bt(&mask,res))
|
||||
goto sm_done;
|
||||
}
|
||||
}
|
||||
SetRFlags(old_flags);
|
||||
}
|
||||
res=MSG_NULL;
|
||||
if (_arg1)
|
||||
*_arg1=0;
|
||||
if (_arg2)
|
||||
*_arg2=0;
|
||||
if (task->parent_task&&task->parent_task->popup_task==task) {
|
||||
SetRFlags(old_flags);
|
||||
return ScanMsg(_arg1,_arg2,mask,task->parent_task);
|
||||
}
|
||||
sm_done:
|
||||
SetRFlags(old_flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 FlushMsgs(CTask *task=NULL)
|
||||
{//Throw away all messages. Return count.
|
||||
I64 res=0,arg1,arg2;
|
||||
while (ScanMsg(&arg1,&arg2,~1,task))
|
||||
res++;
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)
|
||||
{//Wait for a message of type specified by a one in the mask.
|
||||
//Throw-out all messages not in mask.
|
||||
//Returns $LK,"msg_code",A="MN:MSG_CMD"$. See $LK,"::/Demo/MsgLoop.HC"$.
|
||||
I64 res;
|
||||
if (!task) task=Fs;
|
||||
LBtr(&task->task_flags,TASKf_IDLE);
|
||||
while (!(res=ScanMsg(_arg1,_arg2,mask,task))) {
|
||||
LBts(&task->task_flags,TASKf_IDLE);
|
||||
Yield;
|
||||
}
|
||||
LBtr(&task->task_flags,TASKf_IDLE);
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 ScanChar()
|
||||
{//Checks for $LK,"MSG_KEY_DOWN",A="MN:MSG_KEY_DOWN"$ and returns 0 immediately if no key.
|
||||
//Waits for $LK,"MSG_KEY_UP",A="MN:MSG_KEY_UP"$ of non-zero $LK,"ASCII",A="MN:CH_CTRLA"$ key and returns $LK,"ASCII",A="MN:CH_CTRLA"$ if key.
|
||||
//$LK,"ScanMsg",A="MN:ScanMsg"$() throws away other message types.
|
||||
I64 arg1a,arg2a,arg1b,arg2b;
|
||||
if (!ScanMsg(&arg1a,&arg2a,1<<MSG_KEY_DOWN)||!arg1a)
|
||||
return 0;
|
||||
else
|
||||
do GetMsg(&arg1b,&arg2b,1<<MSG_KEY_UP);
|
||||
while (!arg1b); //Be careful of $LK,"SC_SHIFT",A="MN:SC_SHIFT"$ and $LK,"SC_CTRL",A="MN:SC_CTRL"$, etc.
|
||||
return arg1a;
|
||||
}
|
||||
|
||||
Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE)
|
||||
{//Checks for $LK,"MSG_KEY_DOWN",A="MN:MSG_KEY_DOWN"$ and returns FALSE immediately if no key.
|
||||
//Sets $LK,"ASCII",A="MN:CH_CTRLA"$ and $LK,"scan_code",A="FI:::/Doc/CharOverview.DD"$.
|
||||
//Removes key message and returns TRUE.
|
||||
//$LK,"ScanMsg",A="MN:ScanMsg"$() throws away other message types.
|
||||
I64 ch=0,sc=0;
|
||||
if (ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN)) {
|
||||
if (_ch) *_ch=ch;
|
||||
if (_scan_code) *_scan_code=sc;
|
||||
if (echo)
|
||||
PutKey(ch,sc);
|
||||
return TRUE;
|
||||
} else {
|
||||
if (_ch) *_ch=0;
|
||||
if (_scan_code) *_scan_code=0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE,Bool raw_cursor=FALSE)
|
||||
{//Waits for $LK,"MSG_KEY_DOWN",A="MN:MSG_KEY_DOWN"$ message and returns $LK,"ASCII",A="MN:CH_CTRLA"$.
|
||||
//Sets $LK,"scan_code",A="FI:::/Doc/CharOverview.DD"$.
|
||||
//$LK,"ScanKey",A="MN:ScanKey"$() throws away other message types.
|
||||
I64 ch,sc;
|
||||
Bool cursor_on=FALSE;
|
||||
while (!ScanKey(&ch,&sc,FALSE)) {
|
||||
if (IsRaw && raw_cursor) {
|
||||
if (!cursor_on && ToI64(GetTSC*5/cnts.time_stamp_freq)&1) {
|
||||
'Û';
|
||||
cursor_on=TRUE;
|
||||
} else if (cursor_on && !(ToI64(GetTSC*5/cnts.time_stamp_freq)&1)) {
|
||||
'' CH_BACKSPACE;
|
||||
cursor_on=FALSE;
|
||||
}
|
||||
}
|
||||
LBts(&Fs->task_flags,TASKf_IDLE);
|
||||
if (IsDbgMode) {
|
||||
//We don't want interrupt-driven keyboard when in debugger
|
||||
//because that could have side-effects or crash, so we poll
|
||||
//keyboard when in debugger with interrupts off.
|
||||
PUSHFD
|
||||
CLI
|
||||
KbdMsHndlr(TRUE,FALSE);
|
||||
KbdMsgsQue;
|
||||
POPFD
|
||||
} else {
|
||||
LBts(&Fs->task_flags,TASKf_AWAITING_MSG);
|
||||
Yield;
|
||||
}
|
||||
LBtr(&Fs->task_flags,TASKf_IDLE);
|
||||
}
|
||||
if (IsRaw && raw_cursor && cursor_on)
|
||||
'' CH_BACKSPACE;
|
||||
if (echo)
|
||||
PutKey(ch,sc);
|
||||
if (_scan_code) *_scan_code=sc;
|
||||
return ch;
|
||||
}
|
||||
|
||||
I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE)
|
||||
{//Waits for non-zero $LK,"ASCII",A="MN:CH_CTRLA"$ key.
|
||||
//Sets $LK,"scan_code",A="FI:::/Doc/CharOverview.DD"$.
|
||||
I64 ch1;
|
||||
do ch1=GetKey(_scan_code,FALSE,raw_cursor);
|
||||
while (!ch1);
|
||||
if (echo)
|
||||
"$$PT$$%c$$FG$$",ch1;
|
||||
return ch1;
|
||||
}
|
||||
|
||||
U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0)
|
||||
{//Returns a $LK,"MAlloc",A="MN:MAlloc"$()ed prompted string. See $LK,"Flags",A="MN:GSF_SHIFT_ESC_EXIT"$.
|
||||
U8 *st;
|
||||
if (msg)
|
||||
"" msg,dft;
|
||||
st=(*fp_getstr2)(flags);
|
||||
if (!*st) {
|
||||
Free(st);
|
||||
if (dft)
|
||||
return StrNew(dft);
|
||||
else
|
||||
return StrNew("");
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE)
|
||||
{//Prompt into fixed length string. Size must include terminator.
|
||||
U8 *st;
|
||||
I64 ch,i=0;
|
||||
if (!size || !buf) return 0;
|
||||
if (allow_ext) {
|
||||
st=GetStr;
|
||||
if (StrLen(st)>size-1) {
|
||||
MemCpy(buf,st,size-1);
|
||||
buf[size-1]=0;
|
||||
} else
|
||||
StrCpy(buf,st);
|
||||
i=StrLen(buf);
|
||||
Free(st);
|
||||
} else {
|
||||
while (TRUE) {
|
||||
ch=GetChar(,FALSE,IsDbgMode);
|
||||
if (ch=='\n') {
|
||||
'' ch;
|
||||
break;
|
||||
} else if (ch==CH_BACKSPACE) {
|
||||
if (i>0) {
|
||||
i--;
|
||||
'' ch;
|
||||
}
|
||||
} else {
|
||||
if (i<size-1) {
|
||||
buf[i++]=ch;
|
||||
'' ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf[i]=0;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
U0 GridInit()
|
||||
{//Init mouse grid struct. See $LK,"::/Demo/Graphics/Grid.HC"$.
|
||||
ms_grid.x=ms_grid.y=ms_grid.z=8;
|
||||
ms_grid.x_offset=ms_grid.y_offset=ms_grid.z_offset=0;
|
||||
ms_grid.x_speed =ms_grid.y_speed =ms_grid.z_speed =1;
|
||||
ms_grid.show=ms_grid.snap=ms_grid.coord=FALSE;
|
||||
}
|
||||
|
||||
U0 MsUpdate(I64 x,I64 y,I64 z,Bool l,Bool r)
|
||||
{
|
||||
ms.presnap.x=ToI64(ms.scale.x*x)+ms.offset.x;
|
||||
ms.presnap.y=ToI64(ms.scale.y*y)+ms.offset.y;
|
||||
ms.presnap.z=ToI64(ms.scale.z*z)+ms.offset.z;
|
||||
if (ms_grid.snap) {
|
||||
ms.pos.x=Trunc(ms.presnap.x/ms_grid.x)*ms_grid.x+ms_grid.x_offset;
|
||||
ms.pos.y=Trunc(ms.presnap.y/ms_grid.y)*ms_grid.y+ms_grid.y_offset;
|
||||
ms.pos.z=Trunc(ms.presnap.z/ms_grid.z)*ms_grid.z+ms_grid.z_offset;
|
||||
} else {
|
||||
ms.pos.x=ms.presnap.x;
|
||||
ms.pos.y=ms.presnap.y;
|
||||
ms.pos.z=ms.presnap.z;
|
||||
}
|
||||
|
||||
ms.pos.x=ClampI64(ms.pos.x,0,GR_WIDTH-1);
|
||||
ms.pos.y=ClampI64(ms.pos.y,0,GR_HEIGHT-1);
|
||||
ms.pos_text.x=ms.pos.x/FONT_WIDTH;
|
||||
if (ms.pos_text.x>=text.cols) {
|
||||
ms.pos_text.x=text.cols-1;
|
||||
ms.pos.x=text.cols*FONT_WIDTH-1;
|
||||
}
|
||||
ms.pos_text.y=ms.pos.y/FONT_HEIGHT;
|
||||
if (ms.pos_text.y>=text.rows) {
|
||||
ms.pos_text.y=text.rows-1;
|
||||
ms.pos.y=text.rows*FONT_HEIGHT-1;
|
||||
}
|
||||
ms.lb=l;
|
||||
ms.rb=r;
|
||||
LBEqu(&kbd.scan_code,SCf_MS_L_DOWN,ms.lb);
|
||||
LBEqu(&kbd.scan_code,SCf_MS_R_DOWN,ms.rb);
|
||||
}
|
||||
|
||||
U0 MsSet(I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,I64 l=I64_MAX,I64 r=I64_MAX)
|
||||
{//Note: Generates a message. See $LK,"MsSet",A="FF:::/Demo/Games/Zing.HC,MsSet"$().
|
||||
if (!(0<=x<GR_WIDTH))
|
||||
x=ms.pos.x;
|
||||
if (!(0<=y<GR_HEIGHT))
|
||||
y=ms.pos.y;
|
||||
if (z==I64_MAX)
|
||||
z=ms.pos.z;
|
||||
|
||||
if (!(FALSE<=l<=TRUE))
|
||||
l=ms.lb;
|
||||
if (!(FALSE<=r<=TRUE))
|
||||
r=ms.rb;
|
||||
|
||||
x=(x-ms.offset.x)/ms.scale.x;
|
||||
y=(y-ms.offset.y)/ms.scale.y;
|
||||
z=(z-ms.offset.z)/ms.scale.z;
|
||||
MsUpdate(x,y,z,l,r);
|
||||
MsHardSet(x,y,z,l,r);
|
||||
}
|
||||
|
||||
U0 MsInit()
|
||||
{
|
||||
MemSet(&ms,0,sizeof(CMsStateGlbls));
|
||||
MemSet(&ms_last,0,sizeof(CMsStateGlbls));
|
||||
ms.offset.x=ms.offset.y=ms.offset.z=0;
|
||||
ms.scale.x=ms.scale.y=ms.scale.z=1.0;
|
||||
ms.pos_text.x=ms.pos_text.y=ms.pos_text.z=0;
|
||||
ms.has_wheel=FALSE;
|
||||
ms.show=TRUE;
|
||||
ms.speed=0;
|
||||
ms.timestamp=GetTSC;
|
||||
ms.dbl_time=0.350;
|
||||
GridInit;
|
||||
}
|
||||
|
||||
U0 MsHardPktRead()
|
||||
{
|
||||
U8 j;
|
||||
if (GetTSC>ms_hard.timestamp+cnts.time_stamp_freq>>3)
|
||||
FifoU8Flush(ms_hard.fifo);
|
||||
ms_hard.timestamp=GetTSC;
|
||||
FifoU8Ins(ms_hard.fifo,InU8(KBD_PORT));
|
||||
if (FifoU8Cnt(ms_hard.fifo)==ms_hard.pkt_size)
|
||||
while (FifoU8Rem(ms_hard.fifo,&j))
|
||||
FifoU8Ins(ms_hard.fifo2,j);
|
||||
}
|
||||
|
||||
interrupt U0 IRQMsHard()
|
||||
{
|
||||
CLD
|
||||
OutU8(0xA0,0x20);
|
||||
OutU8(0x20,0x20);
|
||||
ms_hard.irqs_working=TRUE;
|
||||
if (ms_hard.install_in_progress || !ms_hard.installed) {
|
||||
kbd.rst=TRUE;
|
||||
return;
|
||||
}
|
||||
MsHardPktRead;
|
||||
}
|
||||
|
||||
U0 MsHardGetType()
|
||||
{
|
||||
I64 b;
|
||||
KbdMsCmdAck(0xF2);
|
||||
b=KbdCmdRead;
|
||||
if (b==3)
|
||||
ms_hard.has_wheel=TRUE;
|
||||
else if (b==4)
|
||||
ms_hard.has_ext_bttns=TRUE;
|
||||
}
|
||||
|
||||
Bool MsHardRst()
|
||||
{
|
||||
U8 b,*_b;
|
||||
F64 timeout;
|
||||
Bool res=FALSE;
|
||||
|
||||
ms_hard.has_wheel=FALSE;
|
||||
ms_hard.has_ext_bttns=FALSE;
|
||||
|
||||
if (*0x40E(U16 *)==0x9FC0) {
|
||||
_b=0x9FC00+0x30;
|
||||
*_b=1; //This enables my mouse. It might be for one machine.
|
||||
//USB DMA packets, set-up by BIOS to make legacy PS/2?
|
||||
}
|
||||
|
||||
try {
|
||||
KbdCmdFlush;
|
||||
KbdCmdSend(KBD_CTRL,0xAD); //Disable Kbd
|
||||
KbdCmdSend(KBD_CTRL,0xA8); //Enable Mouse
|
||||
|
||||
KbdMsCmdAck(0xFF); //Rst
|
||||
|
||||
timeout=tS+10.0;
|
||||
do
|
||||
try {
|
||||
KbdCmdRead;
|
||||
timeout=0; //force exit
|
||||
} catch
|
||||
Fs->catch_except=TRUE;
|
||||
while (tS<timeout);
|
||||
|
||||
try
|
||||
KbdCmdRead;
|
||||
catch
|
||||
Fs->catch_except=TRUE;
|
||||
|
||||
KbdMsCmdAck(0xF3,200,0xF3,100,0xF3,80);
|
||||
MsHardGetType;
|
||||
KbdMsCmdAck(0xF3,10);
|
||||
MsHardGetType;
|
||||
KbdMsCmdAck(0xE8,0x03,0xE6,0xF3,100,0xF4);
|
||||
res=TRUE;
|
||||
|
||||
//Enable IRQ 12
|
||||
KbdCmdSend(KBD_CTRL,0x20);
|
||||
b=KbdCmdRead;
|
||||
KbdCmdSend(KBD_CTRL,0x60);
|
||||
KbdCmdSend(KBD_PORT,(b|2)&~0x20);
|
||||
|
||||
} catch
|
||||
Fs->catch_except=TRUE;
|
||||
|
||||
//This is been added to override failure
|
||||
//because the mouse sometimes still works.
|
||||
res=TRUE;
|
||||
|
||||
try
|
||||
KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
|
||||
catch
|
||||
Fs->catch_except=TRUE;
|
||||
if (ms_hard.has_wheel || ms_hard.has_ext_bttns)
|
||||
ms_hard.pkt_size=4;
|
||||
else
|
||||
ms_hard.pkt_size=3;
|
||||
if (!res)
|
||||
try
|
||||
KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
|
||||
catch
|
||||
Fs->catch_except=TRUE;
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 MsHardSpeedSet()
|
||||
{
|
||||
I64 dd,tmp;
|
||||
if ((dd=SqrI64(ms_hard_last.pos.x-ms_hard.pos.x)
|
||||
+SqrI64(ms_hard_last.pos.y-ms_hard.pos.y)) &&
|
||||
(tmp=ms_hard.timestamp-ms_hard_last.timestamp))
|
||||
ms_hard.speed=Sqrt(dd)*cnts.time_stamp_freq/tmp;
|
||||
ms_hard_last.timestamp=ms_hard.timestamp;
|
||||
}
|
||||
|
||||
U0 MsHardSetPre()
|
||||
{
|
||||
I64 old_timestamp=ms_hard_last.timestamp;
|
||||
MemCpy(&ms_hard_last,&ms_hard,sizeof(CMsHardStateGlbls));
|
||||
ms_hard_last.timestamp=old_timestamp;
|
||||
}
|
||||
|
||||
U0 MsHardSetPost()
|
||||
{
|
||||
I64 i;
|
||||
ms_hard.pos.x=ms_hard.prescale.x*ms_hard.scale.x*ms_grid.x_speed;
|
||||
ms_hard.pos.y=ms_hard.prescale.y*ms_hard.scale.y*ms_grid.y_speed;
|
||||
ms_hard.pos.z=ms_hard.prescale.z*ms_hard.scale.z*ms_grid.z_speed;
|
||||
|
||||
i=Trunc(ms.scale.x*ms_hard.pos.x/ms_grid.x)*ms_grid.x+ms.offset.x;
|
||||
//TODO ms_grid.x_offset?
|
||||
if (i<0)
|
||||
ms.offset.x-=i;
|
||||
else if (i>=GR_WIDTH)
|
||||
ms.offset.x+=GR_WIDTH-1-i;
|
||||
|
||||
i=Trunc(ms.scale.y*ms_hard.pos.y/ms_grid.y)*ms_grid.y+ms.offset.y;
|
||||
if (i<0)
|
||||
ms.offset.y-=i;
|
||||
else if (i>=GR_HEIGHT)
|
||||
ms.offset.y+=GR_HEIGHT-1-i;
|
||||
|
||||
if (ms_hard.pos.x!=ms_hard_last.pos.x || ms_hard.pos.y!=ms_hard_last.pos.y ||
|
||||
ms_hard.pos.z!=ms_hard_last.pos.z) {
|
||||
ms_hard.evt=TRUE;
|
||||
MsHardSpeedSet;
|
||||
} else
|
||||
for (i=0;i<5;i++)
|
||||
if (ms_hard.bttns[i]!=ms_hard_last.bttns[i]) {
|
||||
ms_hard.evt=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U0 MsHardHndlr()
|
||||
{
|
||||
I64 i,dx,dy,dz;
|
||||
U8 ms_buf[4];
|
||||
|
||||
MsHardSetPre;
|
||||
for (i=0;i<4;i++)
|
||||
ms_buf[i]=0;
|
||||
for (i=0;i<ms_hard.pkt_size;i++)
|
||||
if (!FifoU8Rem(ms_hard.fifo2,&ms_buf[i]))
|
||||
ms_buf[i]=0;
|
||||
|
||||
ms_hard.bttns[0] = ms_buf[0] & 1;
|
||||
ms_hard.bttns[1] = (ms_buf[0] & 2) >> 1;
|
||||
ms_hard.bttns[2] = (ms_buf[0] & 4) >> 2;
|
||||
ms_hard.bttns[3] = (ms_buf[3] & 0x10) >> 4;
|
||||
ms_hard.bttns[4] = (ms_buf[3] & 0x20) >> 5;
|
||||
if (ms_buf[0] & 0x10)
|
||||
dx=ms_buf[1]-256;
|
||||
else
|
||||
dx=ms_buf[1];
|
||||
if (ms_buf[0] & 0x20)
|
||||
dy=256-ms_buf[2];
|
||||
else
|
||||
dy=-ms_buf[2];
|
||||
if (ms_buf[3] & 0x08)
|
||||
dz=ms_buf[3]&7-8;
|
||||
else
|
||||
dz=ms_buf[3]&7;
|
||||
|
||||
ms_hard.prescale.x+=dx;
|
||||
ms_hard.prescale.y+=dy;
|
||||
ms_hard.prescale.z+=dz;
|
||||
|
||||
MsHardSetPost;
|
||||
}
|
||||
|
||||
U0 MsHardSet(I64 x,I64 y,I64 z,I64 l,I64 r)
|
||||
{
|
||||
ms_hard.timestamp=GetTSC;
|
||||
MsHardSetPre;
|
||||
ms_hard.prescale.x=x/ms_hard.scale.x/ms_grid.x_speed;
|
||||
ms_hard.prescale.y=y/ms_hard.scale.y/ms_grid.y_speed;
|
||||
ms_hard.prescale.z=z/ms_hard.scale.z/ms_grid.z_speed;
|
||||
ms_hard.bttns[0]=l;
|
||||
ms_hard.bttns[1]=r;
|
||||
MsHardSetPost;
|
||||
}
|
||||
|
||||
U0 KbdMsRst()
|
||||
{
|
||||
KbdCmdFlush;
|
||||
FifoU8Flush(kbd.fifo2);
|
||||
FifoU8Flush(ms_hard.fifo2);
|
||||
FifoI64Flush(kbd.scan_code_fifo);
|
||||
kbd.scan_code=0;
|
||||
kbd.rst=FALSE;
|
||||
}
|
||||
|
||||
Bool MsHardDrvrInstall(I64 dummy=0) //can be spawned
|
||||
{
|
||||
no_warn dummy;
|
||||
I64 i;
|
||||
ms_hard.install_in_progress=TRUE;
|
||||
OutU8(0xA1,InU8(0xA1)|0x10);
|
||||
ms_hard.installed=ms_hard.irqs_working=FALSE;
|
||||
IntEntrySet(0x2C,&IRQMsHard);
|
||||
for(i=0;i<5;i++)
|
||||
ms_hard.bttns[i]=0;
|
||||
if (i=MsHardRst)
|
||||
OutU8(0xA1,InU8(0xA1)&~0x10);
|
||||
KbdMsRst;
|
||||
ms_hard.install_attempts++;
|
||||
ms_hard.installed=ms_hard.evt=i;
|
||||
ms_hard.install_in_progress=FALSE;
|
||||
return ms_hard.installed;
|
||||
}
|
||||
|
||||
U0 KbdMsHndlr(Bool poll_kbd,Bool poll_ms)
|
||||
{
|
||||
if (ms_hard.install_in_progress) {
|
||||
Yield;
|
||||
return;
|
||||
}
|
||||
if (kbd.rst)
|
||||
KbdMsRst;
|
||||
else {
|
||||
if (poll_ms && ms_hard.installed && !ms_hard.irqs_working) {
|
||||
PUSHFD
|
||||
CLI
|
||||
while (InU8(KBD_CTRL)&1)
|
||||
MsHardPktRead;
|
||||
POPFD
|
||||
}
|
||||
|
||||
if (poll_kbd)
|
||||
while (InU8(KBD_CTRL)&1)
|
||||
KbdPktRead;
|
||||
|
||||
if (kbd.rst)
|
||||
KbdMsRst;
|
||||
else {
|
||||
while (FifoU8Cnt(kbd.fifo2))
|
||||
KbdHndlr;
|
||||
while (FifoU8Cnt(ms_hard.fifo2))
|
||||
if (ms_hard.installed)
|
||||
MsHardHndlr;
|
||||
else
|
||||
KbdMsRst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 KbdMsInit()
|
||||
{
|
||||
MemSet(&kbd,0,sizeof(CKbdStateGlbls));
|
||||
kbd.fifo=FifoU8New(8);
|
||||
kbd.fifo2=FifoU8New(0x1000);
|
||||
kbd.scan_code_fifo=FifoI64New(0x1000);
|
||||
kbd.irqs_working=FALSE;
|
||||
MemSet(&ms_hard,0,sizeof(CMsHardStateGlbls));
|
||||
ms_hard.fifo=FifoU8New(8);
|
||||
ms_hard.fifo2=FifoU8New(0x1000);
|
||||
ms_hard.scale.x=0.5;
|
||||
ms_hard.scale.y=0.5;
|
||||
ms_hard.scale.z=1.0;
|
||||
ms_hard.prescale.x=GR_WIDTH/ms_hard.scale.x/2.0;
|
||||
ms_hard.prescale.y=GR_HEIGHT/ms_hard.scale.y/2.0;
|
||||
ms_hard.prescale.z=0/ms_hard.scale.z;
|
||||
ms_hard.pos.x=GR_WIDTH>>1;
|
||||
ms_hard.pos.y=GR_HEIGHT>>1;
|
||||
MemCpy(&ms_hard_last,&ms_hard,sizeof(CMsHardStateGlbls));
|
||||
}
|
||||
Reference in new issue
Block a user