Authors: Chris Morgan <cmorgan@wpi.edu>, James Abbatiello <abbeyj@wpi.edu>
[wine] / msdos / int16.c
1 /*
2  * DOS interrupt 16h handler
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8
9 #include "config.h"
10 #include "module.h"
11 #include "console.h"
12 #include "wincon.h"
13 #include "debugtools.h"
14 #include "winuser.h"
15 #include "miscemu.h"
16
17 DEFAULT_DEBUG_CHANNEL(int16)
18
19 /**********************************************************************
20  *          INT_Int16Handler
21  *
22  * Handler for int 16h (keyboard)
23  *
24  * NOTE:
25  * 
26  *    KEYB.COM (DOS >3.2) adds functions to this interrupt, they are
27  *    not currently listed here.
28  */
29
30 void WINAPI INT_Int16Handler( CONTEXT86 *context )
31 {
32    switch AH_reg(context) {
33
34    case 0x00: /* Get Keystroke */
35       /* Returns: AH = Scan code
36                   AL = ASCII character */   
37       TRACE("Get Keystroke\n");
38       CONSOLE_GetKeystroke(&AH_reg(context), &AL_reg(context));
39       break;
40
41    case 0x01: /* Check for Keystroke */
42       /* Returns: ZF set if no keystroke */
43       /*          AH = Scan code */
44       /*          AL = ASCII character */
45       TRACE("Check for Keystroke\n");
46       if (!CONSOLE_CheckForKeystroke(&AH_reg(context), &AL_reg(context)))
47       {
48           SET_ZFLAG(context);
49       }
50       else
51       {
52           RESET_ZFLAG(context);
53       }
54       break;
55
56    case 0x02: /* Get Shift Flags */      
57       AL_reg(context) = 0;
58
59       if (GetAsyncKeyState(VK_RSHIFT))
60           AL_reg(context) |= 0x01;
61       if (GetAsyncKeyState(VK_LSHIFT))
62           AL_reg(context) |= 0x02;
63       if (GetAsyncKeyState(VK_LCONTROL) || GetAsyncKeyState(VK_RCONTROL))
64           AL_reg(context) |= 0x04;
65       if (GetAsyncKeyState(VK_LMENU) || GetAsyncKeyState(VK_RMENU))
66           AL_reg(context) |= 0x08;
67       if (GetAsyncKeyState(VK_SCROLL))
68           AL_reg(context) |= 0x10;
69       if (GetAsyncKeyState(VK_NUMLOCK))
70           AL_reg(context) |= 0x20;
71       if (GetAsyncKeyState(VK_CAPITAL))
72           AL_reg(context) |= 0x40;
73       if (GetAsyncKeyState(VK_INSERT))
74           AL_reg(context) |= 0x80;
75       TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context));
76       break;
77
78    case 0x03: /* Set Typematic Rate and Delay */
79       FIXME("Set Typematic Rate and Delay - Not Supported\n");
80       break;
81
82    case 0x09: /* Get Keyboard Functionality */
83       FIXME("Get Keyboard Functionality - Not Supported\n");
84       /* As a temporary measure, say that "nothing" is supported... */
85       AL_reg(context) = 0;
86       break;
87
88    case 0x0a: /* Get Keyboard ID */
89       FIXME("Get Keyboard ID - Not Supported\n");
90       break;
91
92    case 0x10: /* Get Enhanced Keystroke */
93       TRACE("Get Enhanced Keystroke - Partially supported\n");
94       /* Returns: AH = Scan code
95                   AL = ASCII character */   
96       CONSOLE_GetKeystroke(&AH_reg(context), &AL_reg(context));
97       break;
98   
99
100    case 0x11: /* Check for Enhanced Keystroke */
101       /* Returns: ZF set if no keystroke */
102       /*          AH = Scan code */
103       /*          AL = ASCII character */
104       TRACE("Check for Enhanced Keystroke - Partially supported\n");
105       if (!CONSOLE_CheckForKeystroke(&AH_reg(context), &AL_reg(context)))
106       {
107           SET_ZFLAG(context);
108       }
109       else
110       {
111           RESET_ZFLAG(context);
112       }
113       break;
114
115    case 0x12: /* Get Extended Shift States */
116       FIXME("Get Extended Shift States - Not Supported\n");
117       break;
118  
119    default:
120       FIXME("Unknown INT 16 function - 0x%x\n", AH_reg(context));   
121       break;
122
123    }
124 }
125
126 int WINAPI INT_Int16AddChar(BYTE ascii,BYTE scan)
127 {
128   BIOSDATA *data = DOSMEM_BiosData();
129   WORD CurOfs = data->FirstKbdCharPtr;
130   WORD NextOfs = CurOfs + 2;
131
132   if (NextOfs >= data->KbdBufferEnd) NextOfs = data->KbdBufferStart;
133   /* check if buffer is full */
134   if (NextOfs == data->NextKbdCharPtr) return 0;
135
136   /* okay, insert character in ring buffer */
137   ((BYTE*)data)[CurOfs] = ascii;
138   ((BYTE*)data)[CurOfs+1] = scan;
139
140   data->FirstKbdCharPtr = NextOfs;
141   return 1;
142 }