gpfce patch
[fceu.git] / drivers / cli / dos-keyboard.c
CommitLineData
c62d2810 1/* FCE Ultra - NES/Famicom Emulator\r
2 *\r
3 * Copyright notice for this file:\r
4 * Copyright (C) 2002 Ben Parnell\r
5 *\r
6 * This program is free software; you can redistribute it and/or modify\r
7 * it under the terms of the GNU General Public License as published by\r
8 * the Free Software Foundation; either version 2 of the License, or\r
9 * (at your option) any later version.\r
10 *\r
11 * This program is distributed in the hope that it will be useful,\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
14 * GNU General Public License for more details.\r
15 *\r
16 * You should have received a copy of the GNU General Public License\r
17 * along with this program; if not, write to the Free Software\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
19 */\r
20\r
21#include <stdio.h>\r
22#include <signal.h>\r
23#include <string.h>\r
24#include <pc.h>\r
25#include <dpmi.h>\r
26#include <go32.h>\r
27#include "keyscan.h"\r
28\r
29static unsigned char lastsc;\r
30static char keybuf[256];\r
31int newk;\r
32\r
33/* Read scan code from port $60 */\r
34/* Acknowledge interrupt( output $20 to port $20) */\r
35\r
36static void ihandler(_go32_dpmi_registers *r)\r
37{\r
38 unsigned char scode=inp(0x60); /* Get scan code. */\r
39\r
40\r
41 if(scode!=0xE0)\r
42 {\r
43 int offs=0;\r
44\r
45 /* I'm only interested in preserving the independent status of the\r
46 right ALT and CONTROL keys.\r
47 */\r
48 if(lastsc==0xE0)\r
49 if((scode&0x7F)==SCAN_LEFTALT || (scode&0x7F)==SCAN_LEFTCONTROL)\r
50 offs=0x80;\r
51 \r
52\r
53 keybuf[(scode&0x7f)|offs]=((scode&0x80)^0x80);\r
54 newk++;\r
55 }\r
56 lastsc=scode;\r
57\r
58 outp(0x20,0x20); /* Acknowledge interrupt. */\r
59}\r
60\r
61static _go32_dpmi_seginfo KBIBack,KBIBackRM;\r
62static _go32_dpmi_seginfo KBI,KBIRM;\r
63static _go32_dpmi_registers KBIRMRegs;\r
64static int initdone=0;\r
65\r
66int InitKeyboard(void)\r
67{\r
68 /* I'll assume that the keyboard is in the correct scancode mode(translated\r
69 mode 2, I think).\r
70 */\r
71 newk=0;\r
72 memset(keybuf,0,sizeof(keybuf));\r
73 KBIRM.pm_offset=KBI.pm_offset=(int)ihandler;\r
74 KBIRM.pm_selector=KBI.pm_selector=_my_cs();\r
75\r
76 _go32_dpmi_get_real_mode_interrupt_vector(9,&KBIBackRM);\r
77 _go32_dpmi_allocate_real_mode_callback_iret(&KBIRM, &KBIRMRegs);\r
78 _go32_dpmi_set_real_mode_interrupt_vector(9,&KBIRM);\r
79\r
80 _go32_dpmi_get_protected_mode_interrupt_vector(9,&KBIBack);\r
81 _go32_dpmi_allocate_iret_wrapper(&KBI);\r
82 _go32_dpmi_set_protected_mode_interrupt_vector(9,&KBI);\r
83 lastsc=0;\r
84 initdone=1;\r
85 return(1);\r
86}\r
87\r
88void KillKeyboard(void)\r
89{\r
90 if(initdone)\r
91 {\r
92 _go32_dpmi_set_protected_mode_interrupt_vector(9,&KBIBack);\r
93 _go32_dpmi_free_iret_wrapper(&KBI);\r
94\r
95 _go32_dpmi_set_real_mode_interrupt_vector(9,&KBIBackRM);\r
96 _go32_dpmi_free_real_mode_callback(&KBIRM);\r
97 initdone=0;\r
98 }\r
99}\r
100\r
101/* In FCE Ultra, it doesn't matter if the key states change\r
102 in the middle of the keyboard handling code. If you want\r
103 to use this code elsewhere, you may want to memcpy() keybuf\r
104 to another buffer and return that when GetKeyboard() is\r
105 called.\r
106*/\r
107\r
108char *GetKeyboard(void)\r
109{\r
110 return keybuf;\r
111}\r
112\r
113/* Returns 1 on new scan codes generated, 0 on no new scan codes. */\r
114int UpdateKeyboard(void)\r
115{\r
116 int t=newk;\r
117\r
118 if(t)\r
119 {\r
120 asm volatile(\r
121 "subl %%eax,_newk\n\t"\r
122 :\r
123 : "a" (t)\r
124 );\r
125\r
126 if(keybuf[SCAN_LEFTCONTROL] && keybuf[SCAN_C])\r
127 raise(SIGINT);\r
128 return(1);\r
129 }\r
130 return(0);\r
131}\r