This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[m32c sim] various patches


* Add support for Timer A (RA in r8c) to allow a crude periodic timer
  and to test the interrupt subsystem.

* Add support for the "main" console (uart1) being a TCP port.
  Originally intended to allow writing a gdb stub that runs over TCP
  in the simulator, which then runs on the hardware using the serial
  port.

* A few opcode fixes.

Applied.

	* Makefile.in: Add Timer A support.
	* cpu.h (m32c_opcode_pc): New.
	(in_gdb): New.
	* gdb-if.c (sim_open): Add Timer A support.  Support unbuffered
	console.
	* int.c (trigger_interrupt): Manage the U flag properly.
	(trigger_based_interrupt): Likewise.
	(trigger_fixed_interrupt): New.
	(trigger_peripheral_interrupt): New.
	* int.h (trigger_peripheral_interrupt): New.
	* m32c.opc: Use m32c_opcode_pc throughout, as needed.
	(decode_m32c): Detect jump-to-zero with traceback.
	(BRK): Try to do the right thing, keeping track of whether we're
	in gdb or not, and if the user has provided a handler or not.
	(GBRK): Alternate break opcode for gdb, in case the user's app
	needs to use BRK for itself.
	(BRK2): Implement.
	* main.c: Add Timer A support.  Support TCP-based console.
	(setup_tcp_console): New.
	(main): Add Timer A support.  Support TCP-based console.
	* mem.c: Add Timer A support.  Support TCP-based console.
	(mem_ptr): Enhance NULL pointer detection.
	(stdin_ready): New.
	(m32c_sim_restore_console): New.
	(mem_get_byte): Check for console input ready.
	(update_timer_a): New.
	* r8c.opc (SSTR): Use r0l, not r0h.
	(REIT): Fix return frame logic.
	* reg.c (print_flags): New.
	(trace_register_changes): Use it.
	(m32c_dump_all_registers): New.
	* timer_a.h: New.
	
	* load.c: Fix indentation.
	* trace.c: Fix indentation.
	* trace.h: Fix indentation.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/sim/m32c/Makefile.in,v
retrieving revision 1.4
diff -p -U3 -r1.4  Makefile.in
--- Makefile.in	1 Jan 2008 22:53:24 -0000	1.4
+++ Makefile.in	6 Jun 2008 19:17:20 -0000
@@ -20,7 +20,7 @@
 
 ## COMMON_PRE_CONFIG_FRAG
 
-SIM_EXTRA_CFLAGS = -Wall
+SIM_EXTRA_CFLAGS = -Wall -DTIMER_A
 
 SIM_RUN_OBJS = \
 	main.o \
Index: cpu.h
===================================================================
RCS file: /cvs/src/src/sim/m32c/cpu.h,v
retrieving revision 1.4
diff -p -U3 -r1.4  cpu.h
--- cpu.h	1 Jan 2008 22:53:25 -0000	1.4
+++ cpu.h	6 Jun 2008 19:17:20 -0000
@@ -23,6 +23,8 @@ extern int verbose;
 extern int trace;
 extern int enable_counting;
 
+extern int in_gdb;
+
 typedef unsigned char QI;
 typedef unsigned short HI;
 typedef unsigned long SI;
@@ -101,6 +103,10 @@ extern unsigned int b2signbit[];
 extern int b2maxsigned[];
 extern int b2minsigned[];
 
+/* address of the opcode that just decoded, and thus caused the
+   exception.  */
+extern int m32c_opcode_pc;
+
 void init_regs (void);
 void stack_heap_stats (void);
 void set_pointer_width (int bytes);
Index: gdb-if.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/gdb-if.c,v
retrieving revision 1.4
diff -p -U3 -r1.4  gdb-if.c
--- gdb-if.c	1 Jan 2008 22:53:25 -0000	1.4
+++ gdb-if.c	6 Jun 2008 19:17:20 -0000
@@ -58,6 +58,7 @@ sim_open (SIM_OPEN_KIND kind,
 	  struct host_callback_struct *callback,
 	  struct bfd *abfd, char **argv)
 {
+  setbuf (stdout, 0);
   if (open)
     fprintf (stderr, "m32c minisim: re-opened sim\n");
 
@@ -124,7 +125,7 @@ open_objfile (const char *filename)
 
 
 SIM_RC
-sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
+sim_load (SIM_DESC sd, char *prog, struct bfd * abfd, int from_tty)
 {
   check_desc (sd);
 
@@ -139,7 +140,7 @@ sim_load (SIM_DESC sd, char *prog, struc
 }
 
 SIM_RC
-sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
+sim_create_inferior (SIM_DESC sd, struct bfd * abfd, char **argv, char **env)
 {
   check_desc (sd);
 
@@ -608,7 +609,12 @@ sim_resume (SIM_DESC sd, int step, int s
     }
 
   if (step)
-    handle_step (decode_opcode ());
+    {
+      handle_step (decode_opcode ());
+#ifdef TIMER_A
+      update_timer_a ();
+#endif
+    }
   else
     {
       /* We don't clear 'stop' here, because then we would miss
@@ -626,6 +632,9 @@ sim_resume (SIM_DESC sd, int step, int s
 	    }
 
 	  int rc = decode_opcode ();
+#ifdef TIMER_A
+	  update_timer_a ();
+#endif
 
 	  if (!M32C_STEPPED (rc))
 	    {
@@ -634,6 +643,7 @@ sim_resume (SIM_DESC sd, int step, int s
 	    }
 	}
     }
+  m32c_sim_restore_console ();
 }
 
 int
Index: int.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/int.c,v
retrieving revision 1.4
diff -p -U3 -r1.4  int.c
--- int.c	1 Jan 2008 22:53:25 -0000	1.4
+++ int.c	6 Jun 2008 19:17:20 -0000
@@ -23,13 +23,17 @@ along with this program.  If not, see <h
 #include "cpu.h"
 #include "mem.h"
 
-void
-trigger_fixed_interrupt (int addr)
+static void
+trigger_interrupt (int addr, int clear_u)
 {
   int s = get_reg (sp);
   int f = get_reg (flags);
   int p = get_reg (pc);
 
+  if (clear_u)
+    set_flags (FLAGBIT_U, 0);
+  set_flags (FLAGBIT_I | FLAGBIT_D, 0);
+
   if (A16)
     {
       s -= 4;
@@ -46,14 +50,26 @@ trigger_fixed_interrupt (int addr)
       mem_put_hi (s + 4, f);
     }
   put_reg (pc, mem_get_psi (addr));
-  set_flags (FLAGBIT_U | FLAGBIT_I | FLAGBIT_D, 0);
+}
+
+void
+trigger_fixed_interrupt (int addr)
+{
+  trigger_interrupt (addr, 1);
 }
 
 void
 trigger_based_interrupt (int vector)
 {
   int addr = get_reg (intb) + vector * 4;
-  if (vector <= 31)
-    set_flags (FLAGBIT_U, 0);
-  trigger_fixed_interrupt (addr);
+  trigger_interrupt (addr, vector <= 31);
+}
+
+void
+trigger_peripheral_interrupt (int vector, int icaddr)
+{
+  unsigned char old_ic = mem_get_qi (icaddr);
+  int addr = get_reg (intb) + vector * 4;
+  trigger_interrupt (addr, 1);
+  put_reg (flags, (get_reg (flags) & 0x8fff) | ((old_ic & 7) << 12));
 }
Index: int.h
===================================================================
RCS file: /cvs/src/src/sim/m32c/int.h,v
retrieving revision 1.4
diff -p -U3 -r1.4  int.h
--- int.h	1 Jan 2008 22:53:25 -0000	1.4
+++ int.h	6 Jun 2008 19:17:20 -0000
@@ -21,3 +21,4 @@ along with this program.  If not, see <h
 
 extern void trigger_fixed_interrupt (int addr);
 extern void trigger_based_interrupt (int vector);
+extern void trigger_peripheral_interrupt (int vector, int icaddr);
Index: load.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/load.c,v
retrieving revision 1.4
diff -p -U3 -r1.4  load.c
--- load.c	1 Jan 2008 22:53:25 -0000	1.4
+++ load.c	6 Jun 2008 19:17:20 -0000
@@ -54,7 +54,7 @@ m32c_set_mach (unsigned long mach)
 }
 
 void
-m32c_load (bfd *prog)
+m32c_load (bfd * prog)
 {
   asection *s;
   unsigned long mach = bfd_get_mach (prog);
Index: m32c.opc
===================================================================
RCS file: /cvs/src/src/sim/m32c/m32c.opc,v
retrieving revision 1.4
diff -p -U3 -r1.4  m32c.opc
--- m32c.opc	1 Jan 2008 22:53:25 -0000	1.4
+++ m32c.opc	6 Jun 2008 19:17:20 -0000
@@ -49,8 +49,8 @@ getbyte ()
 
 #define GETBYTE() (op[opi++] = getbyte())
 
-#define UNSUPPORTED() unsupported("unsupported", orig_pc)
-#define NOTYET() unsupported("unimplemented", orig_pc)
+#define UNSUPPORTED() unsupported("unsupported", m32c_opcode_pc)
+#define NOTYET() unsupported("unimplemented", m32c_opcode_pc)
 
 static void
 unsupported (char *tag, int orig_pc)
@@ -390,12 +390,14 @@ shift_op (srcdest sd, int arith, int cou
   set_flags (FLAGBIT_O, o ? FLAGBIT_O : 0);
 }
 
+static int pcs[16];
+static int ipcs = 0;
+
 int
 decode_m32c()
 {
   unsigned char op[40];
   int opi;
-  int orig_pc;
   int v, a, b;
   long long ll;
   srcdest sc, dc;
@@ -411,9 +413,20 @@ decode_m32c()
 
 next_opcode:
   opi = 0;
-  orig_pc = get_reg (pc);
+  m32c_opcode_pc = get_reg (pc);
+
+  tprintf("trace: decode pc = %06x\n", m32c_opcode_pc);
 
-  tprintf("trace: decode pc = %06x\n", orig_pc);
+  if (m32c_opcode_pc == 0)
+    {
+      int i;
+      printf("Abort: PC is zero, here from:\n");
+      for (i=0; i<4; i++)
+	printf("  0x%06x\n", pcs[(ipcs+15-i)%16]);
+      return M32C_MAKE_HIT_BREAK ();
+    }
+  pcs[ipcs++] = m32c_opcode_pc;
+  ipcs %= 16;
 
   /** VARY sss 000 001 010 011 100 */
   /** VARY ddd 000 001 010 011 100 */
@@ -564,7 +577,7 @@ next_opcode:
   if ((v & (w ? 0xffff : 0xff)) != 0)
     {
       tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a);
-      put_reg (pc, orig_pc + 2 + a);
+      put_reg (pc, m32c_opcode_pc + 2 + a);
       tprintf("%x\n", get_reg (pc));
     }
 
@@ -666,16 +679,41 @@ next_opcode:
 
   /* We report the break to our caller with the PC still pointing at the 
      breakpoint instruction.  */
-  put_reg (pc, orig_pc);
-  if (verbose)
+  put_reg (pc, m32c_opcode_pc);
+  if (verbose || 1)
     printf("[break]\n");
+  if (in_gdb || (regs.r_intbl == 0 && regs.r_intbh == 0))
+    return M32C_MAKE_HIT_BREAK ();
+  if (mem_get_qi (0xFFFFE7) == 0xff)
+    trigger_based_interrupt (0);
+  else
+    trigger_fixed_interrupt (0xFFFFE4);
+
+  /** 1111 1110				GBRK */
+
+  /* This alternate break, which is not part of the chip's opcode set,
+   is here in case you need to debug a program that itself uses the
+   chip's BRK opcode.  You'll need to modify your copy of GDB to use
+   this opcode instead of the real BRK.  */
+
+  /* GDB Break. */
+  /* We report the break to our caller with the PC still pointing at the 
+     breakpoint instruction.  */
+  put_reg (pc, m32c_opcode_pc);
+  if (verbose || 1)
+    printf("[gdb break]\n");
   return M32C_MAKE_HIT_BREAK ();
 
-  /** 0000 1000				BRK */
+  /** 0000 1000				BRK2 */
 
   if (verbose)
     printf("[break2]\n");
-  return M32C_MAKE_HIT_BREAK ();
+  if (in_gdb)
+    return M32C_MAKE_HIT_BREAK ();
+  if (mem_get_qi (0xFFFFE7) == 0xff)
+    trigger_based_interrupt (0);
+  else
+    trigger_fixed_interrupt (0xFFFFE4);
 
   /** 1101 ddd0 dd11 1bit		BSET dest */
 
@@ -988,12 +1026,12 @@ next_opcode:
   prefix (0, 0, 0);
   v = sign_ext (IMM(1), 8);
   if (condition_true (ccc*2+c))
-    put_reg (pc, orig_pc + 1 + v);
+    put_reg (pc, m32c_opcode_pc + 1 + v);
 
   /** 01dd 101d				JMP.S label */
 
   prefix (0, 0, 0);
-  put_reg (pc, orig_pc + (dd*2+d) + 2);
+  put_reg (pc, m32c_opcode_pc + (dd*2+d) + 2);
 
   /** 1011 1011				JMP.B label */
 
@@ -1005,13 +1043,13 @@ next_opcode:
 	printf("[jmp-to-self detected as exit]\n");
       return M32C_MAKE_HIT_BREAK ();
     }
-  put_reg (pc, orig_pc + 1 + imm);
+  put_reg (pc, m32c_opcode_pc + 1 + imm);
 
   /** 1100 1110				JMP.W label */
 
   prefix (0, 0, 0);
   imm = sign_ext (IMM(2), 16);
-  put_reg (pc, orig_pc + 1 + imm);
+  put_reg (pc, m32c_opcode_pc + 1 + imm);
 
   /** 1100 1100				JMP.A label */
   
@@ -1025,7 +1063,7 @@ next_opcode:
   sc = decode_src23 (sss, ss, 2);
   a = get_src (sc);
   a = sign_ext (a, 16);
-  put_reg (pc, orig_pc + a);
+  put_reg (pc, m32c_opcode_pc + a);
 
   /** 1000 sss0 ss00 0001		JMPI.A src */
 
@@ -1047,7 +1085,7 @@ next_opcode:
   imm = sign_ext (IMM(2), 16);
   put_reg (sp, get_reg (sp) - 4);
   mem_put_si (get_reg (sp), get_reg (pc));
-  put_reg (pc, orig_pc + imm + 1);
+  put_reg (pc, m32c_opcode_pc + imm + 1);
 
   /** 1100 1101				JSR.A label */
 
@@ -1065,7 +1103,7 @@ next_opcode:
   a = sign_ext (a, 16);
   put_reg (sp, get_reg (sp) - 4);
   mem_put_si (get_reg (sp), get_reg (pc));
-  put_reg (pc, orig_pc + a);
+  put_reg (pc, m32c_opcode_pc + a);
 
   /** 1001 sss0 ss00 0001		JSRI.A src */
 
@@ -1917,12 +1955,13 @@ next_opcode:
 
   a = get_reg (a1);
   b = get_reg (r3);
+  v = get_reg (w ? r0 : r0l);
   for (;b;)
     {
       if (w)
-	mem_put_hi(a, r0);
+	mem_put_hi(a, v);
       else
-	mem_put_qi(a, r0 & 0xff);
+	mem_put_qi(a, v);
       a += w ? 2 : 1;
       b --;
     }
Index: main.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/main.c,v
retrieving revision 1.4
diff -p -U3 -r1.4  main.c
--- main.c	1 Jan 2008 22:53:25 -0000	1.4
+++ main.c	6 Jun 2008 19:17:20 -0000
@@ -27,6 +27,12 @@ along with this program.  If not, see <h
 #include <setjmp.h>
 #include <signal.h>
 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+
 #include "bfd.h"
 
 #include "cpu.h"
@@ -34,8 +40,15 @@ along with this program.  If not, see <h
 #include "misc.h"
 #include "load.h"
 #include "trace.h"
+#ifdef TIMER_A
+#include "int.h"
+#include "timer_a.h"
+#endif
 
-static int disassemble = 0;
+extern int m32c_console_ofd;
+extern int m32c_console_ifd;
+
+int m32c_disassemble = 0;
 static unsigned int cycles = 0;
 
 static void
@@ -50,24 +63,79 @@ done (int exit_code)
   exit (exit_code);
 }
 
+static void
+setup_tcp_console (char *portname)
+{
+  int port = atoi (portname);
+  struct sockaddr_in address;
+  int isocket;
+  socklen_t as;
+  unsigned char *a;
+
+  if (port < 1024)
+    {
+      printf ("invalid port number %d\n", port);
+      exit (1);
+    }
+  printf ("waiting for tcp console on port %d\n", port);
+
+  memset (&address, 0, sizeof (address));
+  address.sin_family = AF_INET;
+  address.sin_port = htons (port);
+
+  isocket = socket (AF_INET, SOCK_STREAM, 0);
+  if (isocket < 0)
+    {
+      perror ("socket");
+      exit (1);
+    }
+
+  if (bind (isocket, (struct sockaddr *) &address, sizeof (address)))
+    {
+      perror ("bind");
+      exit (1);
+    }
+  listen (isocket, 2);
+
+  printf ("waiting for connection...\n");
+  as = sizeof (address);
+  m32c_console_ifd = accept (isocket, (struct sockaddr *) &address, &as);
+  if (m32c_console_ifd == -1)
+    {
+      perror ("accept");
+      exit (1);
+    }
+  a = (unsigned char *) (&address.sin_addr.s_addr);
+  printf ("connection from %d.%d.%d.%d\n", a[0], a[1], a[2], a[3]);
+  m32c_console_ofd = m32c_console_ifd;
+}
+
 int
 main (int argc, char **argv)
 {
   int o;
   int save_trace;
   bfd *prog;
+  char *console_port_s = 0;
+
+  setbuf (stdout, 0);
+
+  in_gdb = 0;
 
-  while ((o = getopt (argc, argv, "tvdm:")) != -1)
+  while ((o = getopt (argc, argv, "tc:vdm:")) != -1)
     switch (o)
       {
       case 't':
 	trace++;
 	break;
+      case 'c':
+	console_port_s = optarg;
+	break;
       case 'v':
 	verbose++;
 	break;
       case 'd':
-	disassemble++;
+	m32c_disassemble++;
 	break;
       case 'm':
 	if (strcmp (optarg, "r8c") == 0 || strcmp (optarg, "m16c") == 0)
@@ -83,8 +151,8 @@ main (int argc, char **argv)
 	break;
       case '?':
 	fprintf (stderr,
-                 "usage: run [-v] [-t] [-d] [-m r8c|m16c|m32cm|m32c]"
-                 " program\n");
+		 "usage: run [-v] [-t] [-d] [-m r8c|m16c|m32cm|m32c]"
+		 " program\n");
 	exit (1);
       }
 
@@ -106,8 +174,10 @@ main (int argc, char **argv)
   m32c_load (prog);
   trace = save_trace;
 
-  if (disassemble)
-    sim_disasm_init (prog);
+  if (console_port_s)
+    setup_tcp_console (console_port_s);
+
+  sim_disasm_init (prog);
 
   while (1)
     {
@@ -116,7 +186,7 @@ main (int argc, char **argv)
       if (trace)
 	printf ("\n");
 
-      if (disassemble)
+      if (m32c_disassemble)
 	sim_disasm_one ();
 
       enable_counting = verbose;
@@ -132,5 +202,9 @@ main (int argc, char **argv)
 	assert (M32C_STEPPED (rc));
 
       trace_register_changes ();
+
+#ifdef TIMER_A
+      update_timer_a ();
+#endif
     }
 }
Index: mem.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/mem.c,v
retrieving revision 1.5
diff -p -U3 -r1.5  mem.c
--- mem.c	1 Jan 2008 22:53:25 -0000	1.5
+++ mem.c	6 Jun 2008 19:17:20 -0000
@@ -22,11 +22,21 @@ along with this program.  If not, see <h
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <termios.h>
 
 #include "mem.h"
 #include "cpu.h"
 #include "syscalls.h"
 #include "misc.h"
+#ifdef TIMER_A
+#include "int.h"
+#include "timer_a.h"
+#endif
 
 #define L1_BITS  (10)
 #define L2_BITS  (10)
@@ -38,8 +48,15 @@ along with this program.  If not, see <h
 
 static unsigned char **pt[L1_LEN];
 
+int m32c_console_ifd = 0;
+int m32c_console_ofd = 1;
+
+#ifdef TIMER_A
+Timer_A timer_a;
+#endif
+
 /* [ get=0/put=1 ][ byte size ] */
-static unsigned int mem_counters[2][4];
+static unsigned int mem_counters[2][5];
 
 #define COUNT(isput,bytes)                                      \
   if (verbose && enable_counting) mem_counters[isput][bytes]++
@@ -64,14 +81,23 @@ init_mem (void)
 static unsigned char *
 mem_ptr (address)
 {
+  static int recursing = 0;
   int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1);
   int pt2 = (address >> OFF_BITS) & ((1 << L2_BITS) - 1);
   int pto = address & ((1 << OFF_BITS) - 1);
 
-  if (address == 0)
+  if (address == 0 && !recursing)
     {
-      printf ("NULL pointer dereference\n");
+      recursing = 1;
+      put_reg (pc, m32c_opcode_pc);
+      printf ("NULL pointer dereference at pc=0x%x\n", get_reg (pc));
+      step_result = M32C_MAKE_HIT_BREAK ();
+#if 0
+      /* This code can be re-enabled to help diagnose NULL pointer
+         bugs that aren't debuggable in GDB.  */
+      m32c_dump_all_registers ();
       exit (1);
+#endif
     }
 
   if (pt[pt1] == 0)
@@ -138,7 +164,7 @@ mem_usage_stats ()
   /*       mem foo: 123456789012 123456789012 123456789012 123456789012
             123456789012 */
   printf ("                 byte        short      pointer         long"
-          "        fetch\n");
+	  "        fetch\n");
   printf ("mem get: %12s %12s %12s %12s %12s\n", mcs (0, 1), mcs (0, 2),
 	  mcs (0, 3), mcs (0, 4), mcs (0, 0));
   printf ("mem put: %12s %12s %12s %12s\n", mcs (1, 1), mcs (1, 2),
@@ -167,6 +193,8 @@ e ()
 
 #define E() if (trace) e()
 
+extern int m32c_disassemble;
+
 void
 mem_put_byte (int address, unsigned char value)
 {
@@ -199,21 +227,65 @@ mem_put_byte (int address, unsigned char
 	  }
       }
       break;
+#ifdef TIMER_A
+      /* M32C Timer A */
+    case 0x346:		/* TA0low */
+      timer_a.count = (timer_a.count & 0xff00) | value;
+      timer_a.reload = timer_a.count;
+      break;
+    case 0x347:		/* TA0high */
+      timer_a.count = (timer_a.count & 0x00ff) | (value << 8);
+      timer_a.reload = timer_a.count;
+      break;
+    case 0x340:		/* TABSR */
+      timer_a.bsr = value;
+      break;
+    case 0x356:		/* TA0MR */
+      timer_a.mode = value;
+      break;
+    case 0x35f:		/* TCSPR */
+      timer_a.tcspr = value;
+      break;
+    case 0x006c:		/* TA0IC */
+      timer_a.ic = value;
+      break;
+
+      /* R8C Timer RA */
+    case 0x100:		/* TRACR */
+      timer_a.bsr = value;
+      break;
+    case 0x102:		/* TRAMR */
+      timer_a.mode = value;
+      break;
+    case 0x104:		/* TRA */
+      timer_a.count = value;
+      timer_a.reload = value;
+      break;
+    case 0x103:		/* TRAPRE */
+      timer_a.tcspr = value;
+      break;
+    case 0x0056:		/* TA0IC */
+      timer_a.ic = value;
+      break;
+#endif
 
-    case 0x3aa: /* uart1tx */
+    case 0x2ea:		/* m32c uart1tx */
+    case 0x3aa:		/* m16c uart1tx */
       {
 	static int pending_exit = 0;
 	if (value == 0)
 	  {
 	    if (pending_exit)
 	      {
-		step_result = M32C_MAKE_EXITED(value);
+		step_result = M32C_MAKE_EXITED (value);
 		return;
 	      }
 	    pending_exit = 1;
 	  }
 	else
-	  putchar(value);
+	  {
+	    write (m32c_console_ofd, &value, 1);
+	  }
       }
       break;
 
@@ -301,24 +373,94 @@ mem_get_pc ()
   return *m;
 }
 
+static int console_raw = 0;
+static struct termios attr, oattr;
+
+static int
+stdin_ready ()
+{
+  fd_set ifd;
+  int n;
+  struct timeval t;
+
+  t.tv_sec = 0;
+  t.tv_usec = 0;
+  FD_ZERO (&ifd);
+  FD_SET (m32c_console_ifd, &ifd);
+  n = select (1, &ifd, 0, 0, &t);
+  return n > 0;
+}
+
+void
+m32c_sim_restore_console ()
+{
+  tcsetattr (m32c_console_ifd, TCSANOW, &oattr);
+  console_raw = 0;
+}
+
 static unsigned char
 mem_get_byte (int address)
 {
   unsigned char *m;
   address &= membus_mask;
-  S ("=>");
   m = mem_ptr (address);
   switch (address)
     {
-    case 0x3ad: /* uart1c1 */
-      E();
-      return 2; /* transmitter empty */
-      break;
-    default: 
-      if (trace)
-	printf (" %02x", *m);
-      break;
+    case 0x2ed:		/* m32c uart1c1 */
+    case 0x3ad:		/* m16c uart1c1 */
+
+#if 0
+      if (!console_raw)
+	{
+	  tcgetattr (m32c_console_ifd, &attr);
+	  tcgetattr (m32c_console_ifd, &oattr);
+	  /* We want each key to be sent as the user presses them.  */
+	  attr.c_lflag &= ~(ICANON | ECHO | ECHOE);
+	  tcsetattr (m32c_console_ifd, TCSANOW, &attr);
+	  console_raw = 1;
+	  atexit (m32c_sim_restore_console);
+	}
+#endif
+
+      if (stdin_ready ())
+	return 0x02;		/* tx empty and rx full */
+      else
+	return 0x0a;		/* transmitter empty */
+
+    case 0x2ee:		/* m32c uart1 rx */
+      {
+	char c;
+	read (m32c_console_ifd, &c, 1);
+	if (m32c_console_ifd == 0 && c == 3)	/* Ctrl-C */
+	  {
+	    printf ("Ctrl-C!\n");
+	    exit (0);
+	  }
+
+	if (m32c_console_ifd != 1)
+	  {
+	    if (isgraph (c))
+	      printf ("\033[31m%c\033[0m", c);
+	    else
+	      printf ("\033[31m%02x\033[0m", c);
+	  }
+	return c;
+      }
+
+#ifdef TIMER_A
+    case 0x346:		/* TA0low */
+      return timer_a.count & 0xff;
+    case 0x347:		/* TA0high */
+      return (timer_a.count >> 8) & 0xff;
+    case 0x104:		/* TRA */
+      return timer_a.count;
+#endif
+
     }
+
+  S ("=>");
+  if (trace)
+    printf (" %02x", *m);
   E ();
   return *m;
 }
@@ -395,3 +537,61 @@ sign_ext (int v, int bits)
     }
   return v;
 }
+
+#if TIMER_A
+void
+update_timer_a ()
+{
+  if (timer_a.bsr & 1)
+    {
+      timer_a.prescale--;
+      if (timer_a.prescale < 0)
+	{
+	  if (A24)
+	    {
+	      switch (timer_a.mode & 0xc0)
+		{
+		case 0x00:
+		  timer_a.prescale = 0;
+		  break;
+		case 0x40:
+		  timer_a.prescale = 8;
+		  break;
+		case 0x80:
+		  timer_a.prescale = timer_a.tcspr & 0x0f;
+		  break;
+		case 0xc0:
+		  timer_a.prescale = 32;
+		  break;
+		}
+	    }
+	  else
+	    {
+	      timer_a.prescale = timer_a.tcspr;
+	    }
+	  timer_a.count--;
+	  if (timer_a.count < 0)
+	    {
+	      timer_a.count = timer_a.reload;
+	      if (timer_a.ic & 7)
+		{
+		  if (A24)
+		    mem_put_qi (0x6c, timer_a.ic | 0x08);
+		  else
+		    mem_put_qi (0x56, timer_a.ic | 0x08);
+		}
+	    }
+	}
+    }
+
+  if (regs.r_flags & FLAGBIT_I	/* interrupts enabled */
+      && timer_a.ic & 0x08	/* timer A interrupt triggered */
+      && (timer_a.ic & 0x07) > ((regs.r_flags >> 12) & 0x07))
+    {
+      if (A24)
+	trigger_peripheral_interrupt (12, 0x06c);
+      else
+	trigger_peripheral_interrupt (22, 0x056);
+    }
+}
+#endif
Index: opc2c.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/opc2c.c,v
retrieving revision 1.4
diff -p -U3 -r1.4  opc2c.c
--- opc2c.c	1 Jan 2008 22:53:25 -0000	1.4
+++ opc2c.c	6 Jun 2008 19:17:20 -0000
@@ -472,8 +472,6 @@ log_indirect (Indirect * ind, int byte)
 
   for (i = 0; i < 256; i++)
     {
-      if (ind[i].type == T_unused)
-	continue;
 
       for (j = 0; j < byte; j++)
 	fprintf (sim_log, "%s ", prmb (255, cur_bits[j]));
@@ -490,7 +488,7 @@ log_indirect (Indirect * ind, int byte)
 	  last_c = ind[i].u.op->comment;
 	  break;
 	case T_unused:
-	  fprintf (sim_log, "-\n");
+	  fprintf (sim_log, "unused\n");
 	  break;
 	case T_indirect:
 	  fprintf (sim_log, "indirect\n");
Index: r8c.opc
===================================================================
RCS file: /cvs/src/src/sim/m32c/r8c.opc,v
retrieving revision 1.6
diff -p -U3 -r1.6  r8c.opc
--- r8c.opc	1 Jan 2008 22:53:25 -0000	1.6
+++ r8c.opc	6 Jun 2008 19:17:21 -0000
@@ -1249,9 +1249,9 @@ decode_r8c()
 
   a = get_reg (sp);
   v = (mem_get_hi (a)
-       + 65536 * (mem_get_qi (a+3) & 0x0f));
+       + 4096 * (mem_get_qi (a+3) & 0xf0));
   b = (mem_get_qi (a+2)
-       + 16 * (mem_get_qi (a+3) & 0xf0));
+       + 256 * (mem_get_qi (a+3) & 0xff));
   put_reg (pc, v);
   put_reg (flags, b);
   put_reg (sp, get_reg (sp) + 4);
@@ -1401,7 +1401,7 @@ decode_r8c()
 
   int count = get_reg (r3);
   int s1 = get_reg (a1);
-  v = get_reg (w ? r0 : r0h);
+  v = get_reg (w ? r0 : r0l);
 
   while (count)
     {
Index: reg.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/reg.c,v
retrieving revision 1.5
diff -p -U3 -r1.5  reg.c
--- reg.c	1 Jan 2008 22:53:25 -0000	1.5
+++ reg.c	6 Jun 2008 19:17:21 -0000
@@ -28,6 +28,7 @@ along with this program.  If not, see <h
 int verbose = 0;
 int trace = 0;
 int enable_counting = 0;
+int in_gdb = 1;
 
 regs_type regs;
 int addr_mask = 0xffff;
@@ -75,6 +76,8 @@ int b2minsigned[] = { 0, -128, -32768, -
 
 static regs_type oldregs;
 
+int m32c_opcode_pc;
+
 void
 init_regs (void)
 {
@@ -581,6 +584,17 @@ put_reg_ll (reg_id id, DI v)
     }
 }
 
+static void
+print_flags (int f)
+{
+  int i;
+  static char fn[] = "CDZSBOIU";
+  printf ("%d.", (f >> 12) & 7);
+  for (i = 7; i >= 0; i--)
+    if (f & (1 << i))
+      putchar (fn[i]);
+}
+
 #define TRC(f,n, id) \
   if (oldregs.f != regs.f) \
     { \
@@ -617,6 +631,49 @@ trace_register_changes ()
   TRC (r_usp, "usp", usp);
   TRC (r_isp, "isp", isp);
   TRC (r_pc, "pc", pc);
-  TRC (r_flags, "flags", flags);
+  if (oldregs.r_flags != regs.r_flags)
+    {
+      printf ("  flags ");
+      print_flags (oldregs.r_flags);
+      printf (":");
+      print_flags (regs.r_flags);
+    }
+  printf ("\033[0m\n");
+}
+
+#define DRC(f, n, id) \
+  printf("  %-3s %0*x", n,			       \
+	 reg_bytes[id]*2, (unsigned int)regs.f);       \
+
+void
+m32c_dump_all_registers ()
+{
+  printf ("\033[36mREGS:");
+  DRC (r[0].r_r0, "r0", r0);
+  DRC (r[0].r_r1, "r1", r1);
+  DRC (r[0].r_r2, "r2", r2);
+  DRC (r[0].r_r3, "r3", r3);
+  DRC (r[0].r_a0, "a0", a0);
+  DRC (r[0].r_a1, "a1", a1);
+  DRC (r[0].r_sb, "sb", sb);
+  DRC (r[0].r_fb, "fb", fb);
+  printf ("\n     ");
+  DRC (r[1].r_r0, "r0'", r0);
+  DRC (r[1].r_r1, "r1'", r1);
+  DRC (r[1].r_r2, "r2'", r2);
+  DRC (r[1].r_r3, "r3'", r3);
+  DRC (r[1].r_a0, "a0'", a0);
+  DRC (r[1].r_a1, "a1'", a1);
+  DRC (r[1].r_sb, "sb'", sb);
+  DRC (r[1].r_fb, "fb'", fb);
+  printf ("     \n");
+  DRC (r_intbh, "intbh", intbh);
+  DRC (r_intbl, "intbl", intbl);
+  DRC (r_usp, "usp", usp);
+  DRC (r_isp, "isp", isp);
+  DRC (r_pc, "pc", pc);
+  printf ("  flags ");
+  print_flags (regs.r_flags);
   printf ("\033[0m\n");
+  /*sim_disasm_one (); */
 }
Index: safe-fgets.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/safe-fgets.c,v
retrieving revision 1.4
diff -p -U3 -r1.4  safe-fgets.c
--- safe-fgets.c	1 Jan 2008 22:53:25 -0000	1.4
+++ safe-fgets.c	6 Jun 2008 19:17:21 -0000
@@ -30,7 +30,7 @@ static int line_buf_size = 0;
 #define LBUFINCR 100
 
 char *
-safe_fgets (FILE *f)
+safe_fgets (FILE * f)
 {
   char *line_ptr;
 
Index: safe-fgets.h
===================================================================
RCS file: /cvs/src/src/sim/m32c/safe-fgets.h,v
retrieving revision 1.4
diff -p -U3 -r1.4  safe-fgets.h
--- safe-fgets.h	1 Jan 2008 22:53:25 -0000	1.4
+++ safe-fgets.h	6 Jun 2008 19:17:21 -0000
@@ -22,6 +22,6 @@ along with this program.  If not, see <h
 #ifndef _safe_gets_h_
 #define _safe_gets_h_
 
-char *safe_fgets (FILE *f);
+char *safe_fgets (FILE * f);
 
 #endif
Index: timer_a.h
===================================================================
RCS file: timer_a.h
diff -N  timer_a.h
--- timer_a.h	1 Jan 1970 00:00:00 -0000
+++ timer_a.h	6 Jun 2008 19:17:21 -0000
@@ -0,0 +1,12 @@
+typedef struct
+{
+  int count;
+  int reload;
+  int prescale;
+  int tcspr;
+  unsigned char bsr;
+  unsigned char mode;
+  unsigned char ic;
+} Timer_A;
+
+extern Timer_A timer_a;
Index: trace.c
===================================================================
RCS file: /cvs/src/src/sim/m32c/trace.c,v
retrieving revision 1.4
diff -p -U3 -r1.4  trace.c
--- trace.c	1 Jan 2008 22:53:25 -0000	1.4
+++ trace.c	6 Jun 2008 19:17:21 -0000
@@ -101,7 +101,7 @@ op_printf (char *buf, char *fmt, ...)
 static bfd *current_bfd;
 
 void
-sim_disasm_init (bfd *prog)
+sim_disasm_init (bfd * prog)
 {
   current_bfd = prog;
 }
@@ -253,7 +253,7 @@ sim_disasm_one ()
 		slash++;
 	      printf
 		("========================================"
-                 "=====================================\n");
+		 "=====================================\n");
 	      printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n",
 		      slash, lineno, the_line);
 	    }
@@ -271,7 +271,7 @@ sim_disasm_one ()
 	sym = (min + max) / 2;
 	sa = bfd_asymbol_value (symtab[sym]);
 	/*printf("checking %4d %08x %s\n",
-                 sym, sa, bfd_asymbol_name (symtab[sym])); */
+	   sym, sa, bfd_asymbol_name (symtab[sym])); */
 	if (sa > mypc)
 	  max = sym;
 	else if (sa < mypc)
Index: trace.h
===================================================================
RCS file: /cvs/src/src/sim/m32c/trace.h,v
retrieving revision 1.4
diff -p -U3 -r1.4  trace.h
--- trace.h	1 Jan 2008 22:53:25 -0000	1.4
+++ trace.h	6 Jun 2008 19:17:21 -0000
@@ -19,5 +19,5 @@ You should have received a copy of the G
 along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-void sim_disasm_init (bfd *prog);
+void sim_disasm_init (bfd * prog);
 extern void sim_disasm_one (void);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]