/*
 * DOS interrupt 16h handler
 */

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "config.h"
#include "module.h"
#include "callback.h"
#include "dosexe.h"
#include "wincon.h"
#include "debugtools.h"
#include "windef.h"
#include "wingdi.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");
      INT_Int16ReadChar(&AL_reg(context), &AH_reg(context), FALSE);
      break;

   case 0x01: /* Check for Keystroke */
      /* Returns: ZF set if no keystroke */
      /*          AH = Scan code */
      /*          AL = ASCII character */
      TRACE("Check for Keystroke\n");
      if (!INT_Int16ReadChar(&AL_reg(context), &AH_reg(context), TRUE))
      {
          SET_ZFLAG(context);
      }
      else
      {
          RESET_ZFLAG(context);
      }
      break;

   case 0x02: /* Get Shift Flags */      
      AL_reg(context) = 0;

#if 0  /* FIXME: cannot call USER functions here */
      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;
#endif
      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 */   
      INT_Int16ReadChar(&AL_reg(context), &AH_reg(context), FALSE);
      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 (!INT_Int16ReadChar(&AL_reg(context), &AH_reg(context), TRUE))
      {
          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_Int16ReadChar(BYTE*ascii,BYTE*scan,BOOL peek)
{
  BIOSDATA *data = DOSMEM_BiosData();
  WORD CurOfs = data->NextKbdCharPtr;

  /* check if there's data in buffer */
  if (peek) {
    if (CurOfs == data->FirstKbdCharPtr)
      return 0;
  } else {
    while (CurOfs == data->FirstKbdCharPtr) {
      /* no input available yet, so wait... */
      Dosvm.Wait( -1, 0 );
    }
  }
  /* read from keyboard queue */
  TRACE("(%p,%p,%d) -> %02x %02x\n",ascii,scan,peek,((BYTE*)data)[CurOfs],((BYTE*)data)[CurOfs+1]);
  if (ascii) *ascii = ((BYTE*)data)[CurOfs];
  if (scan) *scan = ((BYTE*)data)[CurOfs+1];
  if (!peek) {
    CurOfs += 2;
    if (CurOfs >= data->KbdBufferEnd) CurOfs = data->KbdBufferStart;
    data->NextKbdCharPtr = CurOfs;
  }
  return 1;
}

int WINAPI INT_Int16AddChar(BYTE ascii,BYTE scan)
{
  BIOSDATA *data = DOSMEM_BiosData();
  WORD CurOfs = data->FirstKbdCharPtr;
  WORD NextOfs = CurOfs + 2;

  TRACE("(%02x,%02x)\n",ascii,scan);
  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;
}
