/*
 * Int67 (EMS) emulation
 *
 * 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
 */

#include <assert.h>
#include "wine/winbase16.h"
#include "dosexe.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(int);

/*
 * EMS page size == 16 kilobytes.
 */
#define EMS_PAGE_SIZE (16*1024)

/*
 * Linear address of EMS page.
 */
#define EMS_PAGE_ADDRESS(base,page) (((char*)base) + EMS_PAGE_SIZE * page)

/*
 * Maximum number of pages that can be allocated using EMS.
 */
#define EMS_MAX_PAGES 1024

/*
 * Maximum number of EMS handles (allocated blocks).
 */
#define EMS_MAX_HANDLES 256

/*
 * Global EMM Import Record.
 * Applications can get address of this record
 * and directly access allocated memory if they use
 * IOCTL interface.
 *
 * FIXME: Missing lots of fields, packing is not correct.
 */

static struct {
  struct {
    UCHAR hindex;  /* handle number */
    BYTE  flags;   /* bit 0: normal handle rather than system handle */
    char  name[8]; /* handle name */
    WORD  pages;   /* allocated pages */
    void *address; /* physical address*/
  } handle[EMS_MAX_HANDLES];

  /* Wine specific fields... */

  int   used_pages;     /* Number of allocated pages. */
  void *frame_address;  /* Address of 64k EMS page frame */
  WORD  frame_selector; /* Segment of 64k EMS page frame */

  struct {
    UCHAR hindex;       /* handle number */
    WORD  logical_page; /* logical page */
  } mapping[4];

  struct {
    UCHAR hindex;       /* handle number */
    WORD  logical_page; /* logical page */
  } mapping_save_area[EMS_MAX_HANDLES][4];

} *EMS_record;

/**********************************************************************
 *          EMS_init
 *
 * Allocates and initialized page frame and EMS global import record.
 */
static void EMS_init(void)
{
  /*
   * Start of 64k EMS frame.
   */
  ULONG base = 0xc0000;

  if(EMS_record)
    return;

  EMS_record = HeapAlloc(GetProcessHeap(),
                         HEAP_ZERO_MEMORY,
                         sizeof(*EMS_record));

  EMS_record->frame_address = (void *)base;
  EMS_record->frame_selector = base >> 4;
}

/**********************************************************************
 *          EMS_alloc
 *
 * Get handle and allocate memory.
 */
static void EMS_alloc( CONTEXT86 *context )
{
  int hindex = 1; /* handle zero is reserved for system */

  while(hindex < EMS_MAX_HANDLES && EMS_record->handle[hindex].address)
    hindex++;

  if(hindex == EMS_MAX_HANDLES) {
    SET_AH( context, 0x85 ); /* status: no more handles available */
  } else {
    int   pages = BX_reg(context);
    void *buffer = HeapAlloc( GetProcessHeap(), 0, pages * EMS_PAGE_SIZE );

    if(!buffer) {
      SET_AH( context, 0x88 ); /* status: insufficient pages available */
    } else {
      EMS_record->handle[hindex].address = buffer;
      EMS_record->handle[hindex].pages = pages;
      EMS_record->used_pages += pages;

      SET_DX( context, hindex ); /* handle to allocated memory*/
      SET_AH( context, 0 );      /* status: ok */
    }
  }
}

/**********************************************************************
 *          EMS_access_name
 *
 * Get/set handle name.
 */
static void EMS_access_name( CONTEXT86 *context )
{
  char *ptr;
  int hindex = DX_reg(context);
  if(hindex < 0 || hindex >= EMS_MAX_HANDLES) {
    SET_AH( context, 0x83 ); /* invalid handle */
    return;
  }

  switch AL_reg(context) {
  case 0x00: /* get name */
    ptr = PTR_REAL_TO_LIN(context->SegEs, DI_reg(context));
    memcpy(ptr, EMS_record->handle[hindex].name, 8);
    SET_AH( context, 0 );
    break;

  case 0x01: /* set name */
    ptr = PTR_REAL_TO_LIN(context->SegDs, SI_reg(context));
    memcpy(EMS_record->handle[hindex].name, ptr, 8);
    SET_AH( context, 0 );
    break;

  default:
    INT_BARF(context,0x67);
    break;
  }
}

/**********************************************************************
 *          EMS_map
 *
 * Map logical page into physical page.
 */
static BYTE EMS_map( WORD physical_page, WORD new_hindex, WORD new_logical_page )
{
  int   old_hindex;
  int   old_logical_page;
  void *physical_address;

  if(physical_page > 3)
    return 0x8b; /* status: invalid physical page */

  old_hindex = EMS_record->mapping[physical_page].hindex;
  old_logical_page = EMS_record->mapping[physical_page].logical_page;
  physical_address = EMS_PAGE_ADDRESS(EMS_record->frame_address, physical_page);

  /* unmap old page */
  if(old_hindex) {
    void *ptr = EMS_PAGE_ADDRESS(EMS_record->handle[old_hindex].address,
                                 old_logical_page);
    memcpy(ptr, physical_address, EMS_PAGE_SIZE);
  }

  /* map new page */
  if(new_hindex && new_logical_page != 0xffff) {
    void *ptr = EMS_PAGE_ADDRESS(EMS_record->handle[new_hindex].address,
                                 new_logical_page);

    if(new_hindex >= EMS_MAX_HANDLES || !EMS_record->handle[new_hindex].address)
      return 0x83; /* status: invalid handle */

    if(new_logical_page >= EMS_record->handle[new_hindex].pages)
      return 0x8a; /* status: invalid logical page */

    memcpy(physical_address, ptr, EMS_PAGE_SIZE);
    EMS_record->mapping[physical_page].hindex = new_hindex;
    EMS_record->mapping[physical_page].logical_page = new_logical_page;
  } else {
    EMS_record->mapping[physical_page].hindex = 0;
    EMS_record->mapping[physical_page].logical_page = 0;
  }

  return 0; /* status: ok */
}

/**********************************************************************
 *          EMS_map_multiple
 *
 * Map multiple logical pages into physical pages.
 */
static void EMS_map_multiple( CONTEXT86 *context )
{
  WORD *ptr = PTR_REAL_TO_LIN(context->SegDs, SI_reg(context));
  BYTE  status = 0;
  int   i;

  for(i=0; i<CX_reg(context) && !status; i++, ptr += 2)
    switch(AL_reg(context)) {
    case 0x00:
      status = EMS_map( ptr[1],
                       DX_reg(context), ptr[0] );
      break;
    case 0x01:
      status = EMS_map( (ptr[1] - EMS_record->frame_selector) >> 10,
                       DX_reg(context), ptr[0] );
      break;
    default:
      status = 0x8f; /* status: undefined subfunction */
    }

  SET_AH( context, status );
}

/**********************************************************************
 *          EMS_free
 *
 * Free memory and release handle.
 */
static void EMS_free( CONTEXT86 *context )
{
  int hindex = DX_reg(context);
  int i;

  if(hindex < 0 || hindex >= EMS_MAX_HANDLES) {
    SET_AH( context, 0x83 ); /* status: invalid handle */
    return;
  }

  if(!EMS_record->handle[hindex].address) {
    SET_AH( context, 0 ); /* status: ok */
    return;
  }

  EMS_record->used_pages -= EMS_record->handle[hindex].pages;

  /* unmap pages */
  for(i=0; i<4; i++)
    if(EMS_record->mapping[i].hindex == hindex)
      EMS_record->mapping[i].hindex = 0;

  /* free block */
  HeapFree( GetProcessHeap(), 0, EMS_record->handle[hindex].address );
  EMS_record->handle[hindex].address = 0;

  SET_AH( context, 0 );    /* status: ok */
}

/**********************************************************************
 *          EMS_save_context
 *
 * Save physical page mappings into handle specific save area.
 */
static void EMS_save_context( CONTEXT86 *context )
{
  WORD h = DX_reg(context);
  int  i;

  for(i=0; i<4; i++) {
    EMS_record->mapping_save_area[h][i].hindex = EMS_record->mapping[i].hindex;
    EMS_record->mapping_save_area[h][i].logical_page = EMS_record->mapping[i].logical_page;
  }

  SET_AX( context, 0 ); /* status: ok */
}


/**********************************************************************
 *          EMS_restore_context
 *
 * Restore physical page mappings from handle specific save area.
 */
static void EMS_restore_context( CONTEXT86 *context )
{
  WORD handle = DX_reg(context);
  int  i;

  for(i=0; i<4; i++) {
    int hindex       = EMS_record->mapping_save_area[handle][i].hindex;
    int logical_page = EMS_record->mapping_save_area[handle][i].logical_page;

    if(EMS_map( i, hindex, logical_page )) {
      SET_AX( context, 0x8e ); /* status: restore of mapping context failed */
      return;
    }
  }

  SET_AX( context, 0 ); /* status: ok */
}

/**********************************************************************
 *          DOSVM_Int67Handler (WINEDOS16.203)
 *
 * Handler for interrupt 67h EMS routines.
 */
void WINAPI DOSVM_Int67Handler( CONTEXT86 *context )
{
  switch AH_reg(context) {

  case 0x40: /* EMS - GET MANAGER STATUS */
    SET_AH( context, 0 ); /* status: ok */
    break;

  case 0x41: /* EMS - GET PAGE FRAME SEGMENT */
    EMS_init();
    SET_BX( context, EMS_record->frame_selector ); /* segment of page frame */
    SET_AH( context, 0 );                          /* status: ok */
    break;

  case 0x42: /* EMS - GET NUMBER OF PAGES */
    EMS_init();
    /* unallocated 16k pages */
    SET_BX( context, EMS_MAX_PAGES - EMS_record->used_pages );
    /* total number of 16k pages */
    SET_DX( context, EMS_MAX_PAGES );
    /* status: ok */
    SET_AH( context, 0 );
    break;

  case 0x43: /* EMS - GET HANDLE AND ALLOCATE MEMORY */
    EMS_init();
    EMS_alloc(context);
    break;

  case 0x44: /* EMS - MAP MEMORY */
    EMS_init();
    SET_AH( context, EMS_map( AL_reg(context), DX_reg(context), BX_reg(context) ) );
    break;

  case 0x45: /* EMS - RELEASE HANDLE AND MEMORY */
    EMS_init();
    EMS_free(context);
    break;

  case 0x46: /* EMS - GET EMM VERSION */
    SET_AL( context, 0x40 ); /* version 4.0 */
    SET_AH( context, 0 );    /* status: ok */
    break;

  case 0x47: /* EMS - SAVE MAPPING CONTEXT */
    EMS_init();
    EMS_save_context(context);
    break;

  case 0x48: /* EMS - RESTORE MAPPING CONTEXT */
    EMS_init();
    EMS_restore_context(context);
    break;

  case 0x49: /* EMS - reserved - GET I/O PORT ADDRESSES */
  case 0x4a: /* EMS - reserved - GET TRANSLATION ARRAY */
    INT_BARF(context,0x67);
    break;

  case 0x4b: /* EMS - GET NUMBER OF EMM HANDLES */
    SET_BX( context, EMS_MAX_HANDLES ); /* EMM handles */
    SET_AH( context, 0 );               /* status: ok */
    break;

  case 0x4c: /* EMS - GET PAGES OWNED BY HANDLE */
  case 0x4d: /* EMS - GET PAGES FOR ALL HANDLES */
  case 0x4e: /* EMS - GET OR SET PAGE MAP */
  case 0x4f: /* EMS 4.0 - GET/SET PARTIAL PAGE MAP */
    INT_BARF(context,0x67);
    break;

  case 0x50: /* EMS 4.0 - MAP/UNMAP MULTIPLE HANDLE PAGES */
    EMS_init();
    EMS_map_multiple(context);
    break;

  case 0x51: /* EMS 4.0 - REALLOCATE PAGES */
  case 0x52: /* EMS 4.0 - GET/SET HANDLE ATTRIBUTES */
    INT_BARF(context,0x67);
    break;

  case 0x53: /* EMS 4.0 - GET/SET HANDLE NAME */
    EMS_init();
    EMS_access_name(context);
    break;

  case 0x54: /* EMS 4.0 - GET HANDLE DIRECTORY */
  case 0x55: /* EMS 4.0 - ALTER PAGE MAP AND JUMP */
  case 0x56: /* EMS 4.0 - ALTER PAGE MAP AND CALL */
  case 0x57: /* EMS 4.0 - MOVE/EXCHANGE MEMORY REGION */
  case 0x58: /* EMS 4.0 - GET MAPPABLE PHYSICAL ADDRESS ARRAY */
    INT_BARF(context,0x67);
    break;

  case 0x59: /* EMS 4.0 - GET EXPANDED MEMORY HARDWARE INFORMATION */
    if(AL_reg(context) == 0x01) {
      EMS_init();
      /* unallocated raw pages */
      SET_BX( context, EMS_MAX_PAGES - EMS_record->used_pages );
      /* total number raw pages */
      SET_DX( context, EMS_MAX_PAGES );
      /* status: ok */
      SET_AH( context, 0 );
    } else
      INT_BARF(context,0x67);
    break;

  case 0x5a: /* EMS 4.0 - ALLOCATE STANDARD/RAW PAGES */
  case 0x5b: /* EMS 4.0 - ALTERNATE MAP REGISTER SET */
  case 0x5c: /* EMS 4.0 - PREPARE EXPANDED MEMORY HARDWARE FOR WARM BOOT */
  case 0x5d: /* EMS 4.0 - ENABLE/DISABLE OS FUNCTION SET FUNCTIONS */
    INT_BARF(context,0x67);
    break;

  case 0xde: /* Virtual Control Program Interface (VCPI) */
    if(AL_reg(context) == 0x00) {
      /*
       * VCPI INSTALLATION CHECK
       * (AH_reg() != 0) means VCPI is not present
       */
      TRACE("- VCPI installation check\n");
      return;
    } else
      INT_BARF(context,0x67);
    break;

  default:
    INT_BARF(context,0x67);
  }
}


/**********************************************************************
 *          EMS_Ioctl_Handler
 *
 * Handler for interrupt 21h IOCTL routine for device "EMMXXXX0".
 */
void WINAPI EMS_Ioctl_Handler( CONTEXT86 *context )
{
  assert(AH_reg(context) == 0x44);

  switch AL_reg(context) {
  case 0x00: /* IOCTL - GET DEVICE INFORMATION */
      RESET_CFLAG(context); /* operation was successful */
      SET_DX( context, 0x4080 ); /* bit 14 (support ioctl read) and
                                 * bit 7 (is_device) */
      break;

  case 0x02: /* EMS - GET MEMORY MANAGER INFORMATION */
      /*
       * This is what is called "Windows Global EMM Import Specification".
       * Undocumented of course! Supports three requests:
       * GET API ENTRY POINT
       * GET EMM IMPORT STRUCTURE ADDRESS
       * GET MEMORY MANAGER VERSION
       */
      INT_BARF(context,0x21);
      break;

  case 0x07: /* IOCTL - GET OUTPUT STATUS */
      RESET_CFLAG(context); /* operation was successful */
      SET_AL( context, 0xff ); /* device is ready */
      break;

  default:
      INT_BARF(context,0x21);
      break;
  }
}
