/*  This file is part of the program GDB, the GNU debugger.
    
    Copyright (C) 1998 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions.
    
    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 2 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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    
    */

#include "sim-main.h"
#include "hw-main.h"

/* DEVICE

   
   mn103iop - mn103002 I/O ports 0-3.

   
   DESCRIPTION
   
   Implements the mn103002 i/o ports as described in the mn103002 user guide.


   PROPERTIES   

   reg = <ioport-addr> <ioport-size> ...


   BUGS

   */


/* The I/O ports' registers' address block */

struct mn103iop_block {
  unsigned_word base;
  unsigned_word bound;
};



enum io_port_register_types {
  P0OUT,
  P1OUT,
  P2OUT,
  P3OUT,
  P0MD,
  P1MD,
  P2MD,
  P3MD,
  P2SS,
  P4SS,
  P0DIR,
  P1DIR,
  P2DIR,
  P3DIR,
  P0IN,
  P1IN,
  P2IN,
  P3IN,
};

#define NR_PORTS  4

enum {
  OUTPUT_BLOCK,
  MODE_BLOCK,
  DED_CTRL_BLOCK,
  CTRL_BLOCK,
  PIN_BLOCK,
  NR_BLOCKS
};

typedef struct _mn10300_ioport {
  unsigned8 output, output_mode, control, pin;
  struct hw_event *event;
} mn10300_ioport;



struct mn103iop {
  struct mn103iop_block block[NR_BLOCKS];
  mn10300_ioport port[NR_PORTS];
  unsigned8      p2ss, p4ss;
};


/* Finish off the partially created hw device.  Attach our local
   callbacks.  Wire up our port names etc */

static hw_io_read_buffer_method mn103iop_io_read_buffer;
static hw_io_write_buffer_method mn103iop_io_write_buffer;

static void
attach_mn103iop_regs (struct hw *me,
		      struct mn103iop *io_port)
{
  int i;
  unsigned_word attach_address;
  int attach_space;
  unsigned attach_size;
  reg_property_spec reg;

  if (hw_find_property (me, "reg") == NULL)
    hw_abort (me, "Missing \"reg\" property");

  for (i=0; i < NR_BLOCKS; ++i )
    {
      if (!hw_find_reg_array_property (me, "reg", i, &reg))
	hw_abort (me, "\"reg\" property must contain five addr/size entries");
      hw_unit_address_to_attach_address (hw_parent (me),
					 &reg.address,
					 &attach_space,
					 &attach_address,
					 me);
      io_port->block[i].base = attach_address;
      hw_unit_size_to_attach_size (hw_parent (me),
				   &reg.size,
				   &attach_size, me);
      io_port->block[i].bound = attach_address + (attach_size - 1);
      hw_attach_address (hw_parent (me),
			 0,
			 attach_space, attach_address, attach_size,
			 me);
    }
}

static void
mn103iop_finish (struct hw *me)
{
  struct mn103iop *io_port;
  int i;

  io_port = HW_ZALLOC (me, struct mn103iop);
  set_hw_data (me, io_port);
  set_hw_io_read_buffer (me, mn103iop_io_read_buffer);
  set_hw_io_write_buffer (me, mn103iop_io_write_buffer);

  /* Attach ourself to our parent bus */
  attach_mn103iop_regs (me, io_port);

  /* Initialize the i/o port registers. */
  for ( i=0; i<NR_PORTS; ++i )
    {
      io_port->port[i].output = 0;
      io_port->port[i].output_mode = 0;
      io_port->port[i].control = 0;
      io_port->port[i].pin = 0;
    }
  io_port->port[2].output_mode = 0xff;
  io_port->p2ss = 0;
  io_port->p4ss = 0x0f;
}


/* read and write */

static int
decode_addr (struct hw *me,
	     struct mn103iop *io_port,
	     unsigned_word address)
{
  unsigned_word offset;
  offset = address - io_port->block[0].base;
  switch (offset)
    {
    case 0x00: return P0OUT;
    case 0x01: return P1OUT;
    case 0x04: return P2OUT;
    case 0x05: return P3OUT;
    case 0x20: return P0MD;
    case 0x21: return P1MD;
    case 0x24: return P2MD;
    case 0x25: return P3MD;
    case 0x44: return P2SS;
    case 0x48: return P4SS;
    case 0x60: return P0DIR;
    case 0x61: return P1DIR;
    case 0x64: return P2DIR;
    case 0x65: return P3DIR;
    case 0x80: return P0IN;
    case 0x81: return P1IN;
    case 0x84: return P2IN;
    case 0x85: return P3IN;
    default: 
      {
	hw_abort (me, "bad address");
	return -1;
      }
    }
}


static void
read_output_reg (struct hw *me,
		 struct mn103iop *io_port,
		 unsigned_word io_port_reg,
		 const void *dest,
		 unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      *(unsigned8 *)dest = io_port->port[io_port_reg].output;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes, 
		io_port_reg);
    }
}


static void
read_output_mode_reg (struct hw *me,
		      struct mn103iop *io_port,
		      unsigned_word io_port_reg,
		      const void *dest,
		      unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      /* check if there are fields which can't be written and
	 take appropriate action depending what bits are set */
      *(unsigned8 *)dest = io_port->port[io_port_reg].output_mode;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes to P%dMD.", nr_bytes, 
		io_port_reg);
    }
}


static void
read_control_reg (struct hw *me,
		  struct mn103iop *io_port,
		  unsigned_word io_port_reg,
		  const void *dest,
		  unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      *(unsigned8 *)dest = io_port->port[io_port_reg].control;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes to P%dDIR.", nr_bytes, 
		io_port_reg);
    }
}


static void
read_pin_reg (struct hw *me,
	      struct mn103iop *io_port,
	      unsigned_word io_port_reg,
	      const void *dest,
	      unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      *(unsigned8 *)dest = io_port->port[io_port_reg].pin;
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes to P%dIN.", nr_bytes, 
		io_port_reg);
    }
}


static void
read_dedicated_control_reg (struct hw *me,
			    struct mn103iop *io_port,
			    unsigned_word io_port_reg,
			    const void *dest,
			    unsigned  nr_bytes)
{
  if ( nr_bytes == 1 )
    {
      /* select on io_port_reg: */
      if ( io_port_reg == P2SS )
	{
	  *(unsigned8 *)dest = io_port->p2ss;
	}
      else
	{
	  *(unsigned8 *)dest = io_port->p4ss;
	}
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes to PSS.", nr_bytes); 
    }
}


static unsigned
mn103iop_io_read_buffer (struct hw *me,
			 void *dest,
			 int space,
			 unsigned_word base,
			 unsigned nr_bytes)
{
  struct mn103iop *io_port = hw_data (me);
  enum io_port_register_types io_port_reg;
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  io_port_reg = decode_addr (me, io_port, base);
  switch (io_port_reg)
    {
    /* Port output registers */
    case P0OUT:
    case P1OUT:
    case P2OUT:
    case P3OUT:
      read_output_reg(me, io_port, io_port_reg-P0OUT, dest, nr_bytes);
      break;

    /* Port output mode registers */
    case P0MD:
    case P1MD:
    case P2MD:
    case P3MD:
      read_output_mode_reg(me, io_port, io_port_reg-P0MD, dest, nr_bytes);
      break;

    /* Port control registers */
    case P0DIR:
    case P1DIR:
    case P2DIR:
    case P3DIR:
      read_control_reg(me, io_port, io_port_reg-P0DIR, dest, nr_bytes);
      break;

    /* Port pin registers */
    case P0IN:
    case P1IN:
    case P2IN:
      read_pin_reg(me, io_port, io_port_reg-P0IN, dest, nr_bytes);
      break;

    case P2SS:
    case P4SS:
      read_dedicated_control_reg(me, io_port, io_port_reg, dest, nr_bytes);
      break;

    default:
      hw_abort(me, "invalid address");
    }

  return nr_bytes;
}     


static void
write_output_reg (struct hw *me,
		  struct mn103iop *io_port,
		  unsigned_word io_port_reg,
		  const void *source,
		  unsigned  nr_bytes)
{
  unsigned8 buf = *(unsigned8 *)source;
  if ( nr_bytes == 1 )
    {
      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
	{
	  hw_abort(me, "Cannot write to read-only bits of P3OUT.");
	}
      else
	{
	  io_port->port[io_port_reg].output = buf;
	}
    }
  else
    {
      hw_abort (me, "bad read size of %d bytes from P%dOUT.", nr_bytes, 
		io_port_reg);
    }
}


static void
write_output_mode_reg (struct hw *me,
		       struct mn103iop *io_port,
		       unsigned_word io_port_reg,
		       const void *source,
		       unsigned  nr_bytes)
{
  unsigned8 buf = *(unsigned8 *)source;
  if ( nr_bytes == 1 )
    {
      /* check if there are fields which can't be written and
	 take appropriate action depending what bits are set */
      if ( ( io_port_reg == 3 && (buf & 0xfc) != 0 )
	   || ( (io_port_reg == 0 || io_port_reg == 1)  && (buf & 0xfe) != 0 ) )
	{
	  hw_abort(me, "Cannot write to read-only bits of output mode register.");
	}
      else
	{
	  io_port->port[io_port_reg].output_mode = buf;
	}
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to P%dMD.", nr_bytes, 
		io_port_reg);
    }
}


static void
write_control_reg (struct hw *me,
		   struct mn103iop *io_port,
		   unsigned_word io_port_reg,
		   const void *source,
		   unsigned  nr_bytes)
{
  unsigned8 buf = *(unsigned8 *)source;
  if ( nr_bytes == 1 )
    {
      if ( io_port_reg == 3 && (buf & 0xfc) != 0 )
	{
	  hw_abort(me, "Cannot write to read-only bits of P3DIR.");
	}
      else
	{
	  io_port->port[io_port_reg].control = buf;
	}
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to P%dDIR.", nr_bytes, 
		io_port_reg);
    }
}


static void
write_dedicated_control_reg (struct hw *me,
			     struct mn103iop *io_port,
			     unsigned_word io_port_reg,
			     const void *source,
			     unsigned  nr_bytes)
{
  unsigned8 buf = *(unsigned8 *)source;
  if ( nr_bytes == 1 )
    {
      /* select on io_port_reg: */
      if ( io_port_reg == P2SS )
	{
	  if ( (buf && 0xfc)  != 0 )
	    {
	      hw_abort(me, "Cannot write to read-only bits in p2ss.");
	    }
	  else
	    {
	      io_port->p2ss = buf;
	    }
	}
      else
	{
	  if ( (buf && 0xf0) != 0 )
	    {
	      hw_abort(me, "Cannot write to read-only bits in p4ss.");
	    }
	  else
	    {
	      io_port->p4ss = buf;
	    }
	}
    }
  else
    {
      hw_abort (me, "bad write size of %d bytes to PSS.", nr_bytes); 
    }
}


static unsigned
mn103iop_io_write_buffer (struct hw *me,
			  const void *source,
			  int space,
			  unsigned_word base,
			  unsigned nr_bytes)
{
  struct mn103iop *io_port = hw_data (me);
  enum io_port_register_types io_port_reg;
  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));

  io_port_reg = decode_addr (me, io_port, base);
  switch (io_port_reg)
    {
    /* Port output registers */
    case P0OUT:
    case P1OUT:
    case P2OUT:
    case P3OUT:
      write_output_reg(me, io_port, io_port_reg-P0OUT, source, nr_bytes);
      break;

    /* Port output mode registers */
    case P0MD:
    case P1MD:
    case P2MD:
    case P3MD:
      write_output_mode_reg(me, io_port, io_port_reg-P0MD, source, nr_bytes);
      break;

    /* Port control registers */
    case P0DIR:
    case P1DIR:
    case P2DIR:
    case P3DIR:
      write_control_reg(me, io_port, io_port_reg-P0DIR, source, nr_bytes);
      break;

    /* Port pin registers */
    case P0IN:
    case P1IN:
    case P2IN:
      hw_abort(me, "Cannot write to pin register.");
      break;

    case P2SS:
    case P4SS:
      write_dedicated_control_reg(me, io_port, io_port_reg, source, nr_bytes);
      break;

    default:
      hw_abort(me, "invalid address");
    }

  return nr_bytes;
}     


const struct hw_descriptor dv_mn103iop_descriptor[] = {
  { "mn103iop", mn103iop_finish, },
  { NULL },
};
