/* mem.c --- memory for RL78 simulator.

   Copyright (C) 2011
   Free Software Foundation, Inc.
   Contributed by Red Hat, Inc.

   This file is part of the GNU simulators.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "opcode/rl78.h"
#include "mem.h"
#include "cpu.h"

#define ILLEGAL_OPCODE 0xff

int rom_limit = 0x100000;
int ram_base = 0xf8000;
unsigned char memory[MEM_SIZE];
#define MASK 0xfffff

unsigned char initted[MEM_SIZE];
int skip_init = 0;

#define tprintf if (trace) printf

void
init_mem (void)
{
  memset (memory, ILLEGAL_OPCODE, sizeof (memory));
  memset (memory + 0xf0000, 0x33, 0x10000);

  memset (initted, 0, sizeof (initted));
  memset (initted + 0xffee0, 1, 0x00120);
  memset (initted + 0xf0000, 1, 0x01000);
}

void
mem_ram_size (int ram_bytes)
{
  ram_base = 0x100000 - ram_bytes;
}

void
mem_rom_size (int rom_bytes)
{
  rom_limit = rom_bytes;
}

/* ---------------------------------------------------------------------- */
/* Note: the RL78 memory map has a few surprises.  For starters, part
   of the first 64k is mapped to the last 64k, depending on an SFR bit
   and how much RAM the chip has.  This is simulated here, as are a
   few peripherals.  */

/* This is stdout.  We only care about the data byte, not the upper byte.  */
#define SDR00	0xfff10
#define SSR00	0xf0100
#define TS0	0xf01b2

/* RL78/G13 multiply/divide peripheral.  */
#define MDUC	0xf00e8
#define MDAL	0xffff0
#define MDAH	0xffff2
#define MDBL	0xffff4
#define MDBH	0xffff6
#define MDCL	0xf00e0
#define MDCH	0xf00e2
static long long mduc_clock = 0;
static int mda_set = 0;
#define MDA_SET  15

static int last_addr_was_mirror;

static int
address_mapping (int address)
{
  address &= MASK;
  if (address >= 0xf1000 && address < ram_base)
    {
      address &= 0xffff;
      tprintf ("&");
      if (memory[RL78_SFR_PMC] & 1)
	{
	  tprintf ("|");
	  address |= 0x10000;
	}
      last_addr_was_mirror = 1;
    }
  else
      last_addr_was_mirror = 0;
    
  return address;
}

static void
mem_put_byte (int address, unsigned char value)
{
  address = address_mapping (address);
  memory [address] = value;
  initted [address] = 1;
  if (address == SDR00)
    {
      putchar (value);
      fflush (stdout);
    }
  if (address == TS0)
    {
      if (timer_enabled == 2)
	{
	  total_clocks = 0;
	  pending_clocks = 0;
	  memset (counts_per_insn, 0, sizeof (counts_per_insn));
	  memory[0xf0180] = 0xff;
	  memory[0xf0181] = 0xff;
	}
      if (value & 1)
	timer_enabled = 1;
      else
	timer_enabled = 0;
    }
  if (address == RL78_SFR_SP && value & 1)
    {
      printf ("Warning: SP value 0x%04x truncated at pc=0x%05x\n", value, pc);
      value &= ~1;
    }
  if (address == MDUC)
    {
      if ((value & 0x81) == 0x81)
	{
	  /* division */
	  mduc_clock = total_clocks;
	}
    }
  if ((address & ~3) == MDAL)
    {
      mda_set |= (1 << (address & 3));
      if (mda_set == MDA_SET)
	{
	  long als, ahs;
	  unsigned long alu, ahu;
	  long rvs;
	  long mdc;
	  unsigned long rvu;
	  mda_set = 0;
	  switch (memory [MDUC] & 0xc8)
	    {
	    case 0x00:
	      alu = mem_get_hi (MDAL);
	      ahu = mem_get_hi (MDAH);
	      rvu = alu * ahu;
	      tprintf  ("MDUC: %lu * %lu = %lu\n", alu, ahu, rvu);
	      mem_put_si (MDBL, rvu);
	      break;
	    case 0x08:
	      als = sign_ext (mem_get_hi (MDAL), 16);
	      ahs = sign_ext (mem_get_hi (MDAH), 16);
	      rvs = als * ahs;
	      tprintf  ("MDUC: %ld * %ld = %ld\n", als, ahs, rvs);
	      mem_put_si (MDBL, rvs);
	      break;
	    case 0x40:
	      alu = mem_get_hi (MDAL);
	      ahu = mem_get_hi (MDAH);
	      rvu = alu * ahu;
	      mem_put_si (MDBL, rvu);
	      mdc = mem_get_si (MDCL);
	      tprintf  ("MDUC: %lu * %lu + %lu = ", alu, ahu, mdc);
	      mdc += (long) rvu;
	      tprintf ("%lu\n", mdc);
	      mem_put_si (MDCL, mdc);
	      break;
	    case 0x48:
	      als = sign_ext (mem_get_hi (MDAL), 16);
	      ahs = sign_ext (mem_get_hi (MDAH), 16);
	      rvs = als * ahs;
	      mem_put_si (MDBL, rvs);
	      mdc = mem_get_si (MDCL);
	      tprintf  ("MDUC: %ld * %ld + %ld = ", als, ahs, mdc);
	      tprintf ("%ld\n", mdc);
	      mdc += rvs;
	      mem_put_si (MDCL, mdc);
	      break;
	    }
	}
    }
}

extern long long total_clocks;

static unsigned char
mem_get_byte (int address)
{
  address = address_mapping (address);
  switch (address)
    {
    case SSR00:
    case SSR00 + 1:
      return 0x00;
    case 0xf00f0:
      return 0;
    case 0xf0180:
    case 0xf0181:
      return memory[address];

    case MDUC:
      {
	unsigned char mduc = memory [MDUC];
	if ((mduc & 0x81) == 0x81
	    && total_clocks > mduc_clock + 16)
	  {
	    unsigned long a, b, q, r;
	    memory [MDUC] &= 0xfe;
	    a = mem_get_si (MDAL);
	    b = mem_get_si (MDAL);
	    if (b == 0)
	      {
		q = ~0;
		r = ~0;
	      }
	    else
	      {
		q = a / b;
		r = a % b;
	      }
	    tprintf  ("MDUC: %lu / %lu = q %lu, r %lu\n", a, b, q, r);
	    mem_put_si (MDAL, q);
	    mem_put_si (MDCL, r);
	  }
	return memory[address];
      }
    case MDCL:
    case MDCL + 1:
    case MDCH:
    case MDCH + 1:
      return memory[address];
    }
  if (address < 0xf1000 && address >= 0xf0000)
    {
#if 1
      /* Note: comment out this return to trap the invalid access
	 instead of returning an "undefined" value.  */
      return 0x11;
#else
      fprintf (stderr, "SFR access error: addr 0x%05x pc 0x%05x\n", address, pc);
      exit (1);
#endif
    }
#if 0
  /* Uncomment this block if you want to trap on reads from unwritten memory.  */
  if (!skip_init && !initted [address])
    {
      static int uninit_count = 0;
      fprintf (stderr, "\033[31mwarning :read from uninit addr %05x pc %05x\033[0m\n", address, pc);
      uninit_count ++;
      if (uninit_count > 5)
	exit (1);
    }
#endif
  return memory [address];
}

extern jmp_buf decode_jmp_buf;
#define DO_RETURN(x) longjmp (decode_jmp_buf, x)

#define CHECK_ALIGNMENT(a,v,m) \
  if (a & m) { printf ("Misalignment addr 0x%05x val 0x%04x pc %05x\n", (int)a, (int)v, (int)pc); \
    DO_RETURN (RL78_MAKE_HIT_BREAK ()); }

/* ---------------------------------------------------------------------- */
#define SPECIAL_ADDR(a) (0xffff0 <= a || (0xffee0 <= a && a < 0xfff00))

void
mem_put_qi (int address, unsigned char value)
{
  if (!SPECIAL_ADDR (address))
    tprintf ("\033[34m([%05X]<-%02X)\033[0m", address, value);
  mem_put_byte (address, value);
}

void
mem_put_hi (int address, unsigned short value)
{
  if (!SPECIAL_ADDR (address))
    tprintf ("\033[34m([%05X]<-%04X)\033[0m", address, value);
  CHECK_ALIGNMENT (address, value, 1);
  if (address > 0xffff8 && address != RL78_SFR_SP)
    {
      tprintf ("Word access to 0x%05x!!\n", address);
      DO_RETURN (RL78_MAKE_HIT_BREAK ());
    }
  mem_put_byte (address, value);
  mem_put_byte (address + 1, value >> 8);
}

void
mem_put_psi (int address, unsigned long value)
{
  tprintf ("\033[34m([%05X]<-%06lX)\033[0m", address, value);
  mem_put_byte (address, value);
  mem_put_byte (address + 1, value >> 8);
  mem_put_byte (address + 2, value >> 16);
}

void
mem_put_si (int address, unsigned long value)
{
  tprintf ("\033[34m([%05X]<-%08lX)\033[0m", address, value);
  CHECK_ALIGNMENT (address, value, 3);
  mem_put_byte (address, value);
  mem_put_byte (address + 1, value >> 8);
  mem_put_byte (address + 2, value >> 16);
  mem_put_byte (address + 3, value >> 24);
}

void
mem_put_blk (int address, const void *bufptr, int nbytes)
{
  const unsigned char *bp = (unsigned char *)bufptr;
  while (nbytes --)
    mem_put_byte (address ++, *bp ++);
}

unsigned char
mem_get_pc (int address)
{
  /* Catch obvious problems.  */
  if (address >= rom_limit && address < 0xf0000)
    return 0xff;
  /* This does NOT go through the flash mirror area; you cannot
     execute out of the mirror.  */
  return memory [address & MASK];
}

unsigned char
mem_get_qi (int address)
{
  int v;
  v = mem_get_byte (address);
  if (!SPECIAL_ADDR (address))
    tprintf ("\033[35m([%05X]->%04X)\033[0m", address, v);
  if (last_addr_was_mirror)
    {
      pending_clocks += 3;
      tprintf ("ROM read\n");
    }
  return v;
}

unsigned short
mem_get_hi (int address)
{
  int v;
  v = mem_get_byte (address)
    | mem_get_byte (address + 1) * 256;
  CHECK_ALIGNMENT (address, v, 1);
  if (!SPECIAL_ADDR (address))
    tprintf ("\033[35m([%05X]->%04X)\033[0m", address, v);
  if (last_addr_was_mirror)
    {
      pending_clocks += 3;
      tprintf ("ROM read\n");
    }
  return v;
}

unsigned long
mem_get_psi (int address)
{
  int v;
  v = mem_get_byte (address)
    | mem_get_byte (address + 1) * 256
    | mem_get_byte (address + 2) * 65536;
  tprintf ("\033[35m([%05X]->%04X)\033[0m", address, v);
  return v;
}

unsigned long
mem_get_si (int address)
{
  int v;
  v = mem_get_byte (address)
    | mem_get_byte (address + 1) * 256
    | mem_get_byte (address + 2) * 65536
    | mem_get_byte (address + 2) * 16777216;
  CHECK_ALIGNMENT (address, v, 3);
  tprintf ("(\033[35m[%05X]->%04X)\033[0m", address, v);
  return v;
}

void
mem_get_blk (int address, void *bufptr, int nbytes)
{
  unsigned char *bp = (unsigned char *)bufptr;
  while (nbytes --)
    *bp ++ = mem_get_byte (address ++);
}

int
sign_ext (int v, int bits)
{
  if (bits < 8 * sizeof (int))
    {
      v &= (1 << bits) - 1;
      if (v & (1 << (bits - 1)))
	v -= (1 << bits);
    }
  return v;
}
