/*
 * DOS Virtual Machine
 *
 * Copyright 1998 Ove Kåven
 * Copyright 2002 Jukka Heinonen
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * Note: This code hasn't been completely cleaned up yet.
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>

#include "wine/winbase16.h"
#include "wine/exception.h"
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wingdi.h"
#include "winuser.h"
#include "wownt32.h"
#include "winnt.h"
#include "wincon.h"

#include "dosexe.h"
#include "wine/debug.h"
#include "excpt.h"

WINE_DEFAULT_DEBUG_CHANNEL(int);
WINE_DECLARE_DEBUG_CHANNEL(module);
#ifdef MZ_SUPPORTED
WINE_DECLARE_DEBUG_CHANNEL(relay);
#endif

WORD DOSVM_psp = 0;
WORD DOSVM_retval = 0;

/*
 * Wine DOS memory layout above 640k:
 *
 *   a0000 - affff : VGA graphics         (vga.c)
 *   b0000 - bffff : Monochrome text      (unused)
 *   b8000 - bffff : VGA text             (vga.c)
 *   c0000 - cffff : EMS frame            (int67.c)
 *   d0000 - effff : Free memory for UMBs (himem.c)
 *   f0000 - fffff : BIOS stuff           (msdos/dosmem.c)
 *  100000 -10ffff : High memory area     (unused)
 */

/*
 * Table of real mode segments and protected mode selectors
 * for code stubs and other miscellaneous storage.
 */
struct DPMI_segments *DOSVM_dpmi_segments = NULL;

/*
 * First and last address available for upper memory blocks.
 */
#define DOSVM_UMB_BOTTOM 0xd0000
#define DOSVM_UMB_TOP    0xeffff

/*
 * First free address for upper memory blocks.
 */
static DWORD DOSVM_umb_free = DOSVM_UMB_BOTTOM;


typedef struct _DOSEVENT {
  int irq,priority;
  DOSRELAY relay;
  void *data;
  struct _DOSEVENT *next;
} DOSEVENT, *LPDOSEVENT;

static struct _DOSEVENT *pending_event, *current_event;
static HANDLE event_notifier;

static CRITICAL_SECTION qcrit;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &qcrit,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": qcrit") }
};
static CRITICAL_SECTION qcrit = { &critsect_debug, -1, 0, 0, 0, 0 };


/***********************************************************************
 *              DOSVM_HasPendingEvents
 *
 * Return true if there are pending events that are not
 * blocked by currently active event.
 */
static BOOL DOSVM_HasPendingEvents( void )
{   
    if (!pending_event)
        return FALSE;

    if (!current_event)
        return TRUE;

    if (pending_event->priority < current_event->priority)
        return TRUE;

    return FALSE;
}


/***********************************************************************
 *              DOSVM_SendOneEvent
 *
 * Process single pending event.
 *
 * This function should be called with queue critical section locked. 
 * The function temporarily releases the critical section if it is 
 * possible that internal interrupt handler or user procedure will 
 * be called. This is because we may otherwise get a deadlock if
 * another thread is waiting for the same critical section.
 */
static void DOSVM_SendOneEvent( CONTEXT86 *context )
{
    LPDOSEVENT event = pending_event;

    /* Remove from pending events list. */
    pending_event = event->next;

    /* Process active event. */
    if (event->irq >= 0) 
    {
        BYTE intnum = (event->irq < 8) ?
            (event->irq + 8) : (event->irq - 8 + 0x70);
            
        /* Event is an IRQ, move it to current events list. */
        event->next = current_event;
        current_event = event;

        TRACE( "Dispatching IRQ %d.\n", event->irq );

        if (ISV86(context))
        {
            /* 
             * Note that if DOSVM_HardwareInterruptRM calls an internal 
             * interrupt directly, current_event might be cleared 
             * (and event freed) in this call.
             */
            LeaveCriticalSection(&qcrit);
            DOSVM_HardwareInterruptRM( context, intnum );
            EnterCriticalSection(&qcrit);
        }
        else
        {
            /*
             * This routine only modifies current context so it is
             * not necessary to release critical section.
             */
            DOSVM_HardwareInterruptPM( context, intnum );
        }
    } 
    else 
    {
        /* Callback event. */
        TRACE( "Dispatching callback event.\n" );

        if (ISV86(context))
        {
            /*
             * Call relay immediately in real mode.
             */
            LeaveCriticalSection(&qcrit);
            (*event->relay)( context, event->data );
            EnterCriticalSection(&qcrit);
        }
        else
        {
            /*
             * Force return to relay code. We do not want to
             * call relay directly because we may be inside a signal handler.
             */
            DOSVM_BuildCallFrame( context, event->relay, event->data );
        }

        HeapFree(GetProcessHeap(), 0, event);
    }
}


/***********************************************************************
 *              DOSVM_SendQueuedEvents
 *
 * As long as context instruction pointer stays unmodified,
 * process all pending events that are not blocked by currently
 * active event.
 *
 * This routine assumes that caller has already cleared TEB.vm86_pending 
 * and checked that interrupts are enabled.
 */
void DOSVM_SendQueuedEvents( CONTEXT86 *context )
{   
    DWORD old_cs = context->SegCs;
    DWORD old_ip = context->Eip;

    EnterCriticalSection(&qcrit);

    TRACE( "Called in %s mode %s events pending (time=%d)\n",
           ISV86(context) ? "real" : "protected",
           DOSVM_HasPendingEvents() ? "with" : "without",
           GetTickCount() );
    TRACE( "cs:ip=%04x:%08x, ss:sp=%04x:%08x\n",
           context->SegCs, context->Eip, context->SegSs, context->Esp);

    while (context->SegCs == old_cs &&
           context->Eip == old_ip &&
           DOSVM_HasPendingEvents())
    {
        DOSVM_SendOneEvent(context);

        /*
         * Event handling may have turned pending events flag on.
         * We disable it here because this prevents some
         * unnecessary calls to this function.
         */
        get_vm86_teb_info()->vm86_pending = 0;
    }

#ifdef MZ_SUPPORTED

    if (DOSVM_HasPendingEvents())
    {
        /*
         * Interrupts disabled, but there are still
         * pending events, make sure that pending flag is turned on.
         */
        TRACE( "Another event is pending, setting VIP flag.\n" );
        get_vm86_teb_info()->vm86_pending |= VIP_MASK;
    }

#else

    FIXME("No DOS .exe file support on this platform (yet)\n");

#endif /* MZ_SUPPORTED */

    LeaveCriticalSection(&qcrit);
}


#ifdef MZ_SUPPORTED
/***********************************************************************
 *		DOSVM_QueueEvent
 */
void DOSVM_QueueEvent( INT irq, INT priority, DOSRELAY relay, LPVOID data)
{
  LPDOSEVENT event, cur, prev;
  BOOL       old_pending;

  if (MZ_Current()) {
    event = HeapAlloc(GetProcessHeap(), 0, sizeof(DOSEVENT));
    if (!event) {
      ERR("out of memory allocating event entry\n");
      return;
    }
    event->irq = irq; event->priority = priority;
    event->relay = relay; event->data = data;

    EnterCriticalSection(&qcrit);
    old_pending = DOSVM_HasPendingEvents();

    /* insert event into linked list, in order *after*
     * all earlier events of higher or equal priority */
    cur = pending_event; prev = NULL;
    while (cur && cur->priority<=priority) {
      prev = cur;
      cur = cur->next;
    }
    event->next = cur;
    if (prev) prev->next = event;
    else pending_event = event;

    if (!old_pending && DOSVM_HasPendingEvents()) {
      TRACE("new event queued, signalling (time=%d)\n", GetTickCount());
      
      /* Alert VM86 thread about the new event. */
      kill(dosvm_pid,SIGUSR2);

      /* Wake up DOSVM_Wait so that it can serve pending events. */
      SetEvent(event_notifier);
    } else {
      TRACE("new event queued (time=%d)\n", GetTickCount());
    }

    LeaveCriticalSection(&qcrit);
  } else {
    /* DOS subsystem not running */
    /* (this probably means that we're running a win16 app
     *  which uses DPMI to thunk down to DOS services) */
    if (irq<0) {
      /* callback event, perform it with dummy context */
      CONTEXT86 context;
      memset(&context,0,sizeof(context));
      (*relay)(&context,data);
    } else {
      ERR("IRQ without DOS task: should not happen\n");
    }
  }
}

static void DOSVM_ProcessConsole(void)
{
  INPUT_RECORD msg;
  DWORD res;
  BYTE scan, ascii;

  if (ReadConsoleInputA(GetStdHandle(STD_INPUT_HANDLE),&msg,1,&res)) {
    switch (msg.EventType) {
    case KEY_EVENT:
      scan = msg.Event.KeyEvent.wVirtualScanCode;
      ascii = msg.Event.KeyEvent.uChar.AsciiChar;
      TRACE("scan %02x, ascii %02x\n", scan, ascii);

      /* set the "break" (release) flag if key released */
      if (!msg.Event.KeyEvent.bKeyDown) scan |= 0x80;

      /* check whether extended bit is set,
       * and if so, queue the extension prefix */
      if (msg.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY) {
        DOSVM_Int09SendScan(0xE0,0);
      }
      DOSVM_Int09SendScan(scan, ascii);
      break;
    case MOUSE_EVENT:
      DOSVM_Int33Console(&msg.Event.MouseEvent);
      break;
    case WINDOW_BUFFER_SIZE_EVENT:
      FIXME("unhandled WINDOW_BUFFER_SIZE_EVENT.\n");
      break;
    case MENU_EVENT:
      FIXME("unhandled MENU_EVENT.\n");
      break;
    case FOCUS_EVENT:
      FIXME("unhandled FOCUS_EVENT.\n");
      break;
    default:
      FIXME("unknown console event: %d\n", msg.EventType);
    }
  }
}

static void DOSVM_ProcessMessage(MSG *msg)
{
  BYTE scan = 0;

  TRACE("got message %04x, wparam=%08lx, lparam=%08lx\n",msg->message,msg->wParam,msg->lParam);
  if ((msg->message>=WM_MOUSEFIRST)&&
      (msg->message<=WM_MOUSELAST)) {
    DOSVM_Int33Message(msg->message,msg->wParam,msg->lParam);
  } else {
    switch (msg->message) {
    case WM_KEYUP:
      scan = 0x80;
    case WM_KEYDOWN:
      scan |= (msg->lParam >> 16) & 0x7f;

      /* check whether extended bit is set,
       * and if so, queue the extension prefix */
      if (msg->lParam & 0x1000000) {
	/* FIXME: some keys (function keys) have
	 * extended bit set even when they shouldn't,
	 * should check for them */
	DOSVM_Int09SendScan(0xE0,0);
      }
      DOSVM_Int09SendScan(scan,0);
      break;
    }
  }
}


/***********************************************************************
 *		DOSVM_Wait
 *
 * Wait for asynchronous events. This routine temporarily enables
 * interrupts and waits until some asynchronous event has been 
 * processed.
 */
void DOSVM_Wait( CONTEXT86 *waitctx )
{
    if (DOSVM_HasPendingEvents())
    {
        CONTEXT86 context = *waitctx;
        
        /*
         * If DOSVM_Wait is called from protected mode we emulate
         * interrupt reflection and convert context into real mode context.
         * This is actually the correct thing to do as long as DOSVM_Wait
         * is only called from those interrupt functions that DPMI reflects
         * to real mode.
         *
         * FIXME: Need to think about where to place real mode stack.
         * FIXME: If DOSVM_Wait calls are nested stack gets corrupted.
         *        Can this really happen?
         */
        if (!ISV86(&context))
        {
            context.EFlags |= V86_FLAG;
            context.SegSs = 0xffff;
            context.Esp = 0;
        }

        context.EFlags |= VIF_MASK;
        context.SegCs = 0;
        context.Eip = 0;

        DOSVM_SendQueuedEvents(&context);

        if(context.SegCs || context.Eip)
            DPMI_CallRMProc( &context, NULL, 0, TRUE );
    }
    else
    {
        HANDLE objs[2];
        int    objc = DOSVM_IsWin16() ? 2 : 1;
        DWORD  waitret;

        objs[0] = event_notifier;
        objs[1] = GetStdHandle(STD_INPUT_HANDLE);

        waitret = MsgWaitForMultipleObjects( objc, objs, FALSE, 
                                             INFINITE, QS_ALLINPUT );
        
        if (waitret == WAIT_OBJECT_0)
        {
            /*
             * New pending event has been queued, we ignore it
             * here because it will be processed on next call to
             * DOSVM_Wait.
             */
        }
        else if (objc == 2 && waitret == WAIT_OBJECT_0 + 1)
        {
            DOSVM_ProcessConsole();
        }
        else if (waitret == WAIT_OBJECT_0 + objc)
        {
            MSG msg;
            while (PeekMessageA(&msg,0,0,0,PM_REMOVE|PM_NOYIELD)) 
            {
                /* got a message */
                DOSVM_ProcessMessage(&msg);
                /* we don't need a TranslateMessage here */
                DispatchMessageA(&msg);
            }
        }
        else
        {
            ERR_(module)( "dosvm wait error=%d\n", GetLastError() );
        }
    }
}


DWORD DOSVM_Loop( HANDLE hThread )
{
  HANDLE objs[2];
  int count = 0;
  MSG msg;
  DWORD waitret;

  objs[count++] = hThread;
  if (GetConsoleMode( GetStdHandle(STD_INPUT_HANDLE), NULL ))
      objs[count++] = GetStdHandle(STD_INPUT_HANDLE);

  for(;;) {
      TRACE_(int)("waiting for action\n");
      waitret = MsgWaitForMultipleObjects(count, objs, FALSE, INFINITE, QS_ALLINPUT);
      if (waitret == WAIT_OBJECT_0) {
         DWORD rv;
         if(!GetExitCodeThread(hThread, &rv)) {
             ERR("Failed to get thread exit code!\n");
             rv = 0;
         }
         return rv;
      }
      else if (waitret == WAIT_OBJECT_0 + count) {
          while (PeekMessageA(&msg,0,0,0,PM_REMOVE)) {
              if (msg.hwnd) {
                  /* it's a window message */
                  DOSVM_ProcessMessage(&msg);
                  DispatchMessageA(&msg);
              } else {
                  /* it's a thread message */
                  switch (msg.message) {
                  case WM_QUIT:
                      /* stop this madness!! */
                      return 0;
                  case WM_USER:
                      /* run passed procedure in this thread */
                      /* (sort of like APC, but we signal the completion) */
                      {
                          DOS_SPC *spc = (DOS_SPC *)msg.lParam;
                          TRACE_(int)("calling %p with arg %08lx\n", spc->proc, spc->arg);
                          (spc->proc)(spc->arg);
                          TRACE_(int)("done, signalling event %lx\n", msg.wParam);
                          SetEvent( (HANDLE)msg.wParam );
                      }
                      break;
                  default:
                      DispatchMessageA(&msg);
                  }
              }
          }
      }
      else if (waitret == WAIT_OBJECT_0 + 1)
      {
          DOSVM_ProcessConsole();
      }
      else
      {
          ERR_(int)("MsgWaitForMultipleObjects returned unexpected value.\n");
          return 0;
      }
  }
}

static LONG WINAPI exception_handler(EXCEPTION_POINTERS *eptr)
{
  EXCEPTION_RECORD *rec = eptr->ExceptionRecord;
  CONTEXT *context = eptr->ContextRecord;
  int arg = rec->ExceptionInformation[0];
  BOOL ret;

  switch(rec->ExceptionCode) {
  case EXCEPTION_VM86_INTx:
    TRACE_(relay)("Call DOS int 0x%02x ret=%04x:%04x\n"
                  " eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
                  " ebp=%08x esp=%08x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x\n",
                  arg, context->SegCs, context->Eip,
                  context->Eax, context->Ebx, context->Ecx, context->Edx, context->Esi, context->Edi,
                  context->Ebp, context->Esp, context->SegDs, context->SegEs, context->SegFs, context->SegGs,
                  context->EFlags );
    ret = DOSVM_EmulateInterruptRM( context, arg );
    TRACE_(relay)("Ret  DOS int 0x%02x ret=%04x:%04x\n"
                  " eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
                  " ebp=%08x esp=%08x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x\n",
                  arg, context->SegCs, context->Eip,
                  context->Eax, context->Ebx, context->Ecx, context->Edx, context->Esi, context->Edi,
                  context->Ebp, context->Esp, context->SegDs, context->SegEs,
                  context->SegFs, context->SegGs, context->EFlags );
    return ret ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER;

  case EXCEPTION_VM86_STI:
  /* case EXCEPTION_VM86_PICRETURN: */
    if (!ISV86(context))
      ERR( "Protected mode STI caught by real mode handler!\n" );
    DOSVM_SendQueuedEvents(context);
    return EXCEPTION_CONTINUE_EXECUTION;
  
  case EXCEPTION_SINGLE_STEP:
    ret = DOSVM_EmulateInterruptRM( context, 1 );
    return ret ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER;
  
  case EXCEPTION_BREAKPOINT:
    ret = DOSVM_EmulateInterruptRM( context, 3 );
    return ret ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER;
  
  }
  return EXCEPTION_CONTINUE_SEARCH;
}

INT DOSVM_Enter( CONTEXT86 *context )
{
  INT ret = 0;
  if (!ISV86(context))
      ERR( "Called with protected mode context!\n" );

  __TRY
  {
      if (!WOWCallback16Ex( 0, WCB16_REGS, 0, NULL, (DWORD *)context )) ret = -1;
      TRACE_(module)( "ret %d err %u\n", ret, GetLastError() );
  }
  __EXCEPT(exception_handler)
  {
    TRACE_(module)( "leaving vm86 mode\n" );
  }
  __ENDTRY

  return ret;
}

/***********************************************************************
 *		DOSVM_PIC_ioport_out
 */
void DOSVM_PIC_ioport_out( WORD port, BYTE val)
{
    if (port != 0x20)
    {
        FIXME( "Unsupported PIC port %04x\n", port );
    }
    else if (val == 0x20 || (val >= 0x60 && val <= 0x67)) 
    {
        EnterCriticalSection(&qcrit);

        if (!current_event)
        {
            WARN( "%s without active IRQ\n",
                  val == 0x20 ? "EOI" : "Specific EOI" );
        }
        else if (val != 0x20 && val - 0x60 != current_event->irq)
        {
            WARN( "Specific EOI but current IRQ %d is not %d\n", 
                  current_event->irq, val - 0x60 );
        }
        else
        {
            LPDOSEVENT event = current_event;

            TRACE( "Received %s for current IRQ %d, clearing event\n",
                   val == 0x20 ? "EOI" : "Specific EOI", event->irq );

            current_event = event->next;
            if (event->relay)
                (*event->relay)(NULL,event->data);
            HeapFree(GetProcessHeap(), 0, event);

            if (DOSVM_HasPendingEvents()) 
            {
                TRACE( "Another event pending, setting pending flag\n" );
                get_vm86_teb_info()->vm86_pending |= VIP_MASK;
            }
        }

        LeaveCriticalSection(&qcrit);
    } 
    else 
    {
        FIXME( "Unrecognized PIC command %02x\n", val );
    }
}

#else /* !MZ_SUPPORTED */

/***********************************************************************
 *		DOSVM_Enter
 */
INT DOSVM_Enter( CONTEXT86 *context )
{
    SetLastError( ERROR_NOT_SUPPORTED );
    return -1;
}

/***********************************************************************
 *		DOSVM_Wait
 */
void DOSVM_Wait( CONTEXT86 *waitctx ) { }

/***********************************************************************
 *		DOSVM_PIC_ioport_out
 */
void DOSVM_PIC_ioport_out( WORD port, BYTE val) {}

/***********************************************************************
 *		DOSVM_QueueEvent
 */
void DOSVM_QueueEvent( INT irq, INT priority, DOSRELAY relay, LPVOID data)
{
  if (irq<0) {
    /* callback event, perform it with dummy context */
    CONTEXT86 context;
    memset(&context,0,sizeof(context));
    (*relay)(&context,data);
  } else {
    ERR("IRQ without DOS task: should not happen\n");
  }
}

#endif /* MZ_SUPPORTED */


/**********************************************************************
 *         DOSVM_AcknowledgeIRQ
 *
 * This routine should be called by all internal IRQ handlers.
 */
void WINAPI DOSVM_AcknowledgeIRQ( CONTEXT86 *context )
{
    /*
     * Send EOI to PIC.
     */
    DOSVM_PIC_ioport_out( 0x20, 0x20 );

    /*
     * Protected mode IRQ handlers are supposed
     * to turn VIF flag on before they return.
     */
    if (!ISV86(context))
        get_vm86_teb_info()->dpmi_vif = 1;
}


/***********************************************************************
 *           DOSVM_AllocUMB
 *
 * Allocate upper memory block (UMB) from upper memory.
 * Returned pointer is aligned to 16-byte (paragraph) boundary.
 *
 * This routine is only for allocating static storage for
 * Wine internal uses. Allocated memory can be accessed from
 * real mode, memory is taken from area already mapped and reserved
 * by Wine and the allocation has very little memory and speed
 * overhead. Use of this routine also preserves precious DOS
 * conventional memory.
 */
static LPVOID DOSVM_AllocUMB( DWORD size )
{
  LPVOID ptr = (LPVOID)DOSVM_umb_free;

  size = ((size + 15) >> 4) << 4;

  if(DOSVM_umb_free + size - 1 > DOSVM_UMB_TOP) {
    ERR("Out of upper memory area.\n");
    return 0;
  }

  DOSVM_umb_free += size;
  return ptr;
}


/**********************************************************************
 *          alloc_selector
 *
 * Allocate a selector corresponding to a real mode address.
 * size must be < 64k.
 */
static WORD alloc_selector( void *base, DWORD size, unsigned char flags )
{
    WORD sel = wine_ldt_alloc_entries( 1 );

    if (sel)
    {
        LDT_ENTRY entry;
        wine_ldt_set_base( &entry, base );
        wine_ldt_set_limit( &entry, size - 1 );
        wine_ldt_set_flags( &entry, flags );
        wine_ldt_set_entry( sel, &entry );
    }
    return sel;
}


/***********************************************************************
 *           DOSVM_AllocCodeUMB
 *
 * Allocate upper memory block for storing code stubs.
 * Initializes real mode segment and 16-bit protected mode selector
 * for the allocated code block.
 *
 * FIXME: should allocate a single PM selector for the whole UMB range.
 */
static LPVOID DOSVM_AllocCodeUMB( DWORD size, WORD *segment, WORD *selector )
{
  LPVOID ptr = DOSVM_AllocUMB( size );

  if (segment)
    *segment = (DWORD)ptr >> 4;

  if (selector)
    *selector = alloc_selector( ptr, size, WINE_LDT_FLAGS_CODE );

  return ptr;
}


/***********************************************************************
 *           DOSVM_AllocDataUMB
 *
 * Allocate upper memory block for storing data.
 * Initializes real mode segment and 16-bit protected mode selector
 * for the allocated data block.
 */
LPVOID DOSVM_AllocDataUMB( DWORD size, WORD *segment, WORD *selector )
{
  LPVOID ptr = DOSVM_AllocUMB( size );

  if (segment)
    *segment = (DWORD)ptr >> 4;

  if (selector)
    *selector = alloc_selector( ptr, size, WINE_LDT_FLAGS_DATA );

  return ptr;
}


/***********************************************************************
 *           DOSVM_InitSegments
 *
 * Initializes DOSVM_dpmi_segments. Allocates required memory and
 * sets up segments and selectors for accessing the memory.
 */
void DOSVM_InitSegments(void)
{
    LPSTR ptr;
    int   i;

    static const char wrap_code[]={
     0xCD,0x31, /* int $0x31 */
     0xCB       /* lret */
    };

    static const char enter_xms[]=
    {
        /* XMS hookable entry point */
        0xEB,0x03,           /* jmp entry */
        0x90,0x90,0x90,      /* nop;nop;nop */
                             /* entry: */
        /* real entry point */
        /* for simplicity, we'll just use the same hook as DPMI below */
        0xCD,0x31,           /* int $0x31 */
        0xCB                 /* lret */
    };

    static const char enter_pm[]=
    {
        0x50,                /* pushw %ax */
        0x52,                /* pushw %dx */
        0x55,                /* pushw %bp */
        0x89,0xE5,           /* movw %sp,%bp */
        /* get return CS */
        0x8B,0x56,0x08,      /* movw 8(%bp),%dx */
        /* just call int 31 here to get into protected mode... */
        /* it'll check whether it was called from dpmi_seg... */
        0xCD,0x31,           /* int $0x31 */
        /* we are now in the context of a 16-bit relay call */
        /* need to fixup our stack;
         * 16-bit relay return address will be lost,
         * but we won't worry quite yet
         */
        0x8E,0xD0,           /* movw %ax,%ss */
        0x66,0x0F,0xB7,0xE5, /* movzwl %bp,%esp */
        /* set return CS */
        0x89,0x56,0x08,      /* movw %dx,8(%bp) */
        0x5D,                /* popw %bp */
        0x5A,                /* popw %dx */
        0x58,                /* popw %ax */
        0xfb,                /* sti, enable and check virtual interrupts */
        0xCB                 /* lret */
    };

    static const char relay[]=
    {
        0xca, 0x04, 0x00, /* 16-bit far return and pop 4 bytes (relay void* arg) */
        0xcd, 0x31,       /* int 31 */
        0xfb, 0x66, 0xcb  /* sti and 32-bit far return */
    };

    /*
     * Allocate pointer array.
     */
    DOSVM_dpmi_segments = DOSVM_AllocUMB( sizeof(struct DPMI_segments) );

    /*
     * RM / offset 0: Exit from real mode.
     * RM / offset 2: Points to lret opcode.
     */
    ptr = DOSVM_AllocCodeUMB( sizeof(wrap_code),
                              &DOSVM_dpmi_segments->wrap_seg, 0 );
    memcpy( ptr, wrap_code, sizeof(wrap_code) );

    /*
     * RM / offset 0: XMS driver entry.
     */
    ptr = DOSVM_AllocCodeUMB( sizeof(enter_xms),
                              &DOSVM_dpmi_segments->xms_seg, 0 );
    memcpy( ptr, enter_xms, sizeof(enter_xms) );

    /*
     * RM / offset 0: Switch to DPMI.
     * PM / offset 8: DPMI raw mode switch.
     */
    ptr = DOSVM_AllocCodeUMB( sizeof(enter_pm),
                              &DOSVM_dpmi_segments->dpmi_seg,
                              &DOSVM_dpmi_segments->dpmi_sel );
    memcpy( ptr, enter_pm, sizeof(enter_pm) );

    /*
     * PM / offset N*6: Interrupt N in DPMI32.
     */
    ptr = DOSVM_AllocCodeUMB( 6 * 256,
                              0, &DOSVM_dpmi_segments->int48_sel );
    for(i=0; i<256; i++) {
        /*
         * Each 32-bit interrupt handler is 6 bytes:
         * 0xCD,<i>            = int <i> (nested 16-bit interrupt)
         * 0x66,0xCA,0x04,0x00 = ret 4   (32-bit far return and pop 4 bytes / eflags)
         */
        ptr[i * 6 + 0] = 0xCD;
        ptr[i * 6 + 1] = i;
        ptr[i * 6 + 2] = 0x66;
        ptr[i * 6 + 3] = 0xCA;
        ptr[i * 6 + 4] = 0x04;
        ptr[i * 6 + 5] = 0x00;
    }

    /*
     * PM / offset N*5: Interrupt N in 16-bit protected mode.
     */
    ptr = DOSVM_AllocCodeUMB( 5 * 256,
                              0, &DOSVM_dpmi_segments->int16_sel );
    for(i=0; i<256; i++) {
        /*
         * Each 16-bit interrupt handler is 5 bytes:
         * 0xCD,<i>       = int <i> (interrupt)
         * 0xCA,0x02,0x00 = ret 2   (16-bit far return and pop 2 bytes / eflags)
         */
        ptr[i * 5 + 0] = 0xCD;
        ptr[i * 5 + 1] = i;
        ptr[i * 5 + 2] = 0xCA;
        ptr[i * 5 + 3] = 0x02;
        ptr[i * 5 + 4] = 0x00;
    }

    /*
     * PM / offset 0: Stub where __wine_call_from_16_regs returns.
     * PM / offset 3: Stub which swaps back to 32-bit application code/stack.
     * PM / offset 5: Stub which enables interrupts
     */
    ptr = DOSVM_AllocCodeUMB( sizeof(relay),
                              0,  &DOSVM_dpmi_segments->relay_code_sel);
    memcpy( ptr, relay, sizeof(relay) );

    /*
     * Space for 16-bit stack used by relay code.
     */
    ptr = DOSVM_AllocDataUMB( DOSVM_RELAY_DATA_SIZE,
                              0, &DOSVM_dpmi_segments->relay_data_sel);
    memset( ptr, 0, DOSVM_RELAY_DATA_SIZE );

    /*
     * As we store code in UMB we should make sure it is executable
     */
    VirtualProtect((void *)DOSVM_UMB_BOTTOM, DOSVM_UMB_TOP - DOSVM_UMB_BOTTOM, PAGE_EXECUTE_READWRITE, NULL);

    event_notifier = CreateEventW(NULL, FALSE, FALSE, NULL);
}
