|  | /* | 
|  | * DOS interrupt 16h handler | 
|  | */ | 
|  |  | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  | #include <unistd.h> | 
|  |  | 
|  | #include "config.h" | 
|  | #include "module.h" | 
|  | #include "console.h" | 
|  | #include "wincon.h" | 
|  | #include "debugtools.h" | 
|  | #include "winuser.h" | 
|  | #include "miscemu.h" | 
|  |  | 
|  | DEFAULT_DEBUG_CHANNEL(int16) | 
|  |  | 
|  | /********************************************************************** | 
|  | *	    INT_Int16Handler | 
|  | * | 
|  | * Handler for int 16h (keyboard) | 
|  | * | 
|  | * NOTE: | 
|  | * | 
|  | *    KEYB.COM (DOS >3.2) adds functions to this interrupt, they are | 
|  | *    not currently listed here. | 
|  | */ | 
|  |  | 
|  | void WINAPI INT_Int16Handler( CONTEXT86 *context ) | 
|  | { | 
|  | switch AH_reg(context) { | 
|  |  | 
|  | case 0x00: /* Get Keystroke */ | 
|  | /* Returns: AH = Scan code | 
|  | AL = ASCII character */ | 
|  | TRACE("Get Keystroke\n"); | 
|  | CONSOLE_GetKeystroke(&AH_reg(context), &AL_reg(context)); | 
|  | break; | 
|  |  | 
|  | case 0x01: /* Check for Keystroke */ | 
|  | /* Returns: ZF set if no keystroke */ | 
|  | /*          AH = Scan code */ | 
|  | /*          AL = ASCII character */ | 
|  | TRACE("Check for Keystroke\n"); | 
|  | if (!CONSOLE_CheckForKeystroke(&AH_reg(context), &AL_reg(context))) | 
|  | { | 
|  | SET_ZFLAG(context); | 
|  | } | 
|  | else | 
|  | { | 
|  | RESET_ZFLAG(context); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x02: /* Get Shift Flags */ | 
|  | AL_reg(context) = 0; | 
|  |  | 
|  | if (GetAsyncKeyState(VK_RSHIFT)) | 
|  | AL_reg(context) |= 0x01; | 
|  | if (GetAsyncKeyState(VK_LSHIFT)) | 
|  | AL_reg(context) |= 0x02; | 
|  | if (GetAsyncKeyState(VK_LCONTROL) || GetAsyncKeyState(VK_RCONTROL)) | 
|  | AL_reg(context) |= 0x04; | 
|  | if (GetAsyncKeyState(VK_LMENU) || GetAsyncKeyState(VK_RMENU)) | 
|  | AL_reg(context) |= 0x08; | 
|  | if (GetAsyncKeyState(VK_SCROLL)) | 
|  | AL_reg(context) |= 0x10; | 
|  | if (GetAsyncKeyState(VK_NUMLOCK)) | 
|  | AL_reg(context) |= 0x20; | 
|  | if (GetAsyncKeyState(VK_CAPITAL)) | 
|  | AL_reg(context) |= 0x40; | 
|  | if (GetAsyncKeyState(VK_INSERT)) | 
|  | AL_reg(context) |= 0x80; | 
|  | TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context)); | 
|  | break; | 
|  |  | 
|  | case 0x03: /* Set Typematic Rate and Delay */ | 
|  | FIXME("Set Typematic Rate and Delay - Not Supported\n"); | 
|  | break; | 
|  |  | 
|  | case 0x09: /* Get Keyboard Functionality */ | 
|  | FIXME("Get Keyboard Functionality - Not Supported\n"); | 
|  | /* As a temporary measure, say that "nothing" is supported... */ | 
|  | AL_reg(context) = 0; | 
|  | break; | 
|  |  | 
|  | case 0x0a: /* Get Keyboard ID */ | 
|  | FIXME("Get Keyboard ID - Not Supported\n"); | 
|  | break; | 
|  |  | 
|  | case 0x10: /* Get Enhanced Keystroke */ | 
|  | TRACE("Get Enhanced Keystroke - Partially supported\n"); | 
|  | /* Returns: AH = Scan code | 
|  | AL = ASCII character */ | 
|  | CONSOLE_GetKeystroke(&AH_reg(context), &AL_reg(context)); | 
|  | break; | 
|  |  | 
|  |  | 
|  | case 0x11: /* Check for Enhanced Keystroke */ | 
|  | /* Returns: ZF set if no keystroke */ | 
|  | /*          AH = Scan code */ | 
|  | /*          AL = ASCII character */ | 
|  | TRACE("Check for Enhanced Keystroke - Partially supported\n"); | 
|  | if (!CONSOLE_CheckForKeystroke(&AH_reg(context), &AL_reg(context))) | 
|  | { | 
|  | SET_ZFLAG(context); | 
|  | } | 
|  | else | 
|  | { | 
|  | RESET_ZFLAG(context); | 
|  | } | 
|  | break; | 
|  |  | 
|  | case 0x12: /* Get Extended Shift States */ | 
|  | FIXME("Get Extended Shift States - Not Supported\n"); | 
|  | break; | 
|  |  | 
|  | default: | 
|  | FIXME("Unknown INT 16 function - 0x%x\n", AH_reg(context)); | 
|  | break; | 
|  |  | 
|  | } | 
|  | } | 
|  |  | 
|  | int WINAPI INT_Int16AddChar(BYTE ascii,BYTE scan) | 
|  | { | 
|  | BIOSDATA *data = DOSMEM_BiosData(); | 
|  | WORD CurOfs = data->FirstKbdCharPtr; | 
|  | WORD NextOfs = CurOfs + 2; | 
|  |  | 
|  | if (NextOfs >= data->KbdBufferEnd) NextOfs = data->KbdBufferStart; | 
|  | /* check if buffer is full */ | 
|  | if (NextOfs == data->NextKbdCharPtr) return 0; | 
|  |  | 
|  | /* okay, insert character in ring buffer */ | 
|  | ((BYTE*)data)[CurOfs] = ascii; | 
|  | ((BYTE*)data)[CurOfs+1] = scan; | 
|  |  | 
|  | data->FirstKbdCharPtr = NextOfs; | 
|  | return 1; | 
|  | } |