/*
 * DANG_BEGIN_MODULE
 * 
 * PHASE1 initialization:
 *
 * This is where you initialize anything necessary to create a virtual
 * PC configuration.  Intialize the cpu, the various chips (pic, pit, etc.)
 * and then setup & initialize the BIOS, etc.
 * 
 * DANG_END_MODULE
 * 
 * DANG_BEGIN_CHANGELOG
 *
 * $Date: $
 * $Source: $
 * $Revision: $
 * $State: $
 *
 * $Log: $
 *
 * DANG_END_CHANGELOG
 */

#include "dosemu.h"
#include "base/memory.h"
#include "base/misc.h"

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/times.h>
#include <sys/time.h>
#include <sys/stat.h>

/*
 * DANG_BEGIN_FUNCTION map_hardware_ram
 *
 * description:
 *  Initialize the hardware direct-mapped pages
 * 
 * DANG_END_FUNCTION
 */
static inline void map_hardware_ram(void)
{
  int i, j;
  unsigned int addr, size;

  if (!config.must_spare_hardware_ram)
    return;

  if (mem_fd < 0) {
    g_printf("MAP: unable to map hardware ram because /proc/mem not open\n");
    return;
  }

  for (i = 0; i < sizeof(config.hardware_pages) - 1; i++) {
    if (config.hardware_pages[i++]) {
      j = i - 1;
      while (config.hardware_pages[i])
	i++;		/* NOTE: last byte is always ZERO */
      addr = HARDWARE_RAM_START + (j << 12);
      size = (i - j) << 12;
      if (mmap((caddr_t) addr, (size_t) size, PROT_READ | PROT_WRITE, 
	       MAP_SHARED | MAP_FIXED, mem_fd, addr) < 0) {
	error("ERROR: mmap error in map_hardware_ram %s\n", strerror (errno));
	return;
      }
      g_printf("MPA: hardware ram at 0x%05x .. 0x%05x\n", addr, addr+size-1);
    }
  }
}

/* 
 * DANG_BEGIN_FUNCTION low_mem_init
 *
 * description:
 *  Initializes the lower 1Meg via mmap & sets up the HMA region
 *
 * DANG_END_FUNCTION
 */
static inline void low_mem_init(void)
{
  char *result;
  g_printf("INIT: DOS memory area being mapped in\n");
  result = mmap (NULL, 0x100000,
                 PROT_EXEC | PROT_READ | PROT_WRITE,
                 MAP_FIXED | MAP_PRIVATE | MAP_ANON,
                 -1, 0);
  if (result != NULL) {
    perror ("anonymous mmap");
    leavedos (1);
  }

  map_hardware_ram();
}

void emulator_init(void)
{
  low_mem_init();
}

void emulator_reset(void)
{
}
