/* Target-machine dependent code for WDC-65816, for GDB.
   Copyright (C) 1995 Free Software Foundation, Inc.

   This file is part of GDB.

   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.  */

/*
   Contributed by Steve Chamberlain
   sac@cygnus.com
 */

#include "defs.h"
#include "frame.h"
#include "obstack.h"
#include "symtab.h"
#include "gdbcmd.h"
#include "gdbtypes.h"
#include "dis-asm.h"
#include "gdbcore.h"

/* Return the saved PC from this frame. */


CORE_ADDR
w65_frame_saved_pc (struct frame_info *frame)
{
  return (read_memory_integer (frame->frame + 2, 4) & 0xffffff);
}

CORE_ADDR
w65_addr_bits_remove (CORE_ADDR addr)
{
  return ((addr) & 0xffffff);
}

read_memory_pointer (CORE_ADDR x)
{
  return read_memory_integer (ADDR_BITS_REMOVE (x), 4);
}

init_frame_pc (void)
{
  abort ();
}

void
w65_push_dummy_frame (void)
{
  abort ();
}

/* Put here the code to store, into a struct frame_saved_regs,
   the addresses of the saved registers of frame described by FRAME_INFO.
   This includes special registers such as pc and fp saved in special
   ways in the stack frame.  sp is even more special:
   the address we return for it IS the sp for the next frame.

   We cache the result of doing this in the frame_cache_obstack, since
   it is fairly expensive.  */

void
frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
{
  int locals;
  CORE_ADDR pc;
  CORE_ADDR adr;
  int i;

  memset (fsrp, 0, sizeof *fsrp);
}

int
saved_pc_after_call (void)
{
  int sp = read_register (SP_REGNUM);
  int val = read_memory_integer (sp + 1, 4);
  return ADDR_BITS_REMOVE (val);
}


extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
  int b;
  int len = TYPE_LENGTH (type);

  for (b = 0; b < len; b += 2)
    {
      int todo = len - b;
      if (todo > 2)
	todo = 2;
      memcpy (valbuf + b, regbuf + b, todo);
    }
}

void
write_return_value (struct type *type, char *valbuf)
{
  int reg;
  int len;
  for (len = 0; len < TYPE_LENGTH (type); len += 2)
    {
      write_register_bytes (REGISTER_BYTE (len / 2 + 2), valbuf + len, 2);
    }
}

void
store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
  write_register (2, addr);
}

void
w65_pop_frame (void)
{
}

init_extra_frame_info (void)
{
}

pop_frame (void)
{
}

w65_frame_chain (struct frame_info *thisframe)
{
  return 0xffff & read_memory_integer ((thisframe)->frame, 2);
}

static int
gb (int x)
{
  return read_memory_integer (x, 1) & 0xff;
}

extern CORE_ADDR
w65_skip_prologue (CORE_ADDR pc)
{
  CORE_ADDR too_far = pc + 20;

  /* looking for bits of the prologue, we can expect to
     see this in a frameful function:

     stack adjust:

     3B                 tsc
     1A                 inc a
     18                 clc
     69E2FF             adc     #0xffe2
     3A                 dec a
     1B                 tcs
     1A                 inc a

     link:

     A500               lda     <r15
     48                 pha
     3B                 tsc
     1a                 inc     a
     8500               sta     <r15

   */

#define TSC  0x3b
#define TCS  0x1b
#define INCA 0x1a
#define PHA  0x48
#define LDADIR 0xa5
#define STADIR 0x85

  /* Skip a stack adjust - any area between a tsc and tcs */
  if (gb (pc) == TSC)
    {
      while (pc < too_far && gb (pc) != TCS)
	{
	  pc++;
	}
      pc++;
      /* Skip a stupid inc a */
      if (gb (pc) == INCA)
	pc++;

    }
  /* Stack adjust can also be done with n pha's */
  while (gb (pc) == PHA)
    pc++;

  /* Skip a link - that's a ld/ph/tsc/inc/sta */

  if (gb (pc) == LDADIR
      && gb (pc + 5) == STADIR
      && gb (pc + 1) == gb (pc + 6)
      && gb (pc + 2) == PHA
      && gb (pc + 3) == TSC
      && gb (pc + 4) == INCA)
    {
      pc += 7;
    }

  return pc;
}


register_raw_size (int n)
{
  return sim_reg_size (n);
}


void
print_register_hook (int regno)
{
  if (regno == P_REGNUM)
    {
      /* CCR register */

      int C, Z, N, V, I, D, X, M;
      unsigned char b[1];
      unsigned char l;

      read_relative_register_raw_bytes (regno, b);
      l = b[0];
      printf_unfiltered ("\t");
      C = (l & 0x1) != 0;
      Z = (l & 0x2) != 0;
      I = (l & 0x4) != 0;
      D = (l & 0x8) != 0;
      X = (l & 0x10) != 0;
      M = (l & 0x20) != 0;
      V = (l & 0x40) != 0;
      N = (l & 0x80) != 0;

      printf_unfiltered ("N-%d ", N);
      printf_unfiltered ("V-%d ", V);
      printf_unfiltered ("M-%d ", M);
      printf_unfiltered ("X-%d ", X);
      printf_unfiltered ("D-%d ", D);
      printf_unfiltered ("I-%d ", I);
      printf_unfiltered ("Z-%d ", Z);
      printf_unfiltered ("C-%d ", C);
      if ((C | Z) == 0)
	printf_unfiltered ("u> ");
      if ((C | Z) == 1)
	printf_unfiltered ("u<= ");
      if ((C == 0))
	printf_unfiltered ("u>= ");
      if (C == 1)
	printf_unfiltered ("u< ");
      if (Z == 0)
	printf_unfiltered ("!= ");
      if (Z == 1)
	printf_unfiltered ("== ");
      if ((N ^ V) == 0)
	printf_unfiltered (">= ");
      if ((N ^ V) == 1)
	printf_unfiltered ("< ");
      if ((Z | (N ^ V)) == 0)
	printf_unfiltered ("> ");
      if ((Z | (N ^ V)) == 1)
	printf_unfiltered ("<= ");
    }
}

void
_initialize_w65_tdep (void)
{
  tm_print_insn = print_insn_w65;
}
