This is the mail archive of the gdb-patches@sources.redhat.com 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]

[PATCH]: Support call/rtc for 68HC12 simulator


Hi!

The 68HC12 has a memory bank switching mechanism which can be used
with the call and rtc instructions.  A 16K window at 0x8000 is controlled
by a page register which is saved & set by 'call' and restored by 'rtc' (ret from call).

I've committed this patch (mainline) to add support for call/rtc in the simulator and give
access to the page register.  Also fixes some warnings.

	Stephane

2002-08-13  Stephane Carrez  <stcarrez@nerim.fr>

	* m68hc11_sim.c (cpu_special): Handle call and rtc instructions.
	* sim-main.h (M6812_CALL_INDIRECT): Add to enum.
	(m6811_regs): Add page register.
	(cpu_set_page, cpu_get_page): New macros.
	(phys_to_virt): New function.
	(cpu_get_indexed_operand_addr, cpu_return): Declare.
	* gencode.c: Identify indirect addressing mode for call and fix daa.
	(gen_function_entry): New param to tell if src8/dst8 locals are
	necessary.
	(gen_interpreter): Use it to avoid generation of unused variables.
	* interp.c (sim_fetch_register): Allow to read page register; page
	register, A, B and CCR are only 1 byte wide.
	(sim_store_register): Likewise for writing.
Index: gencode.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/gencode.c,v
retrieving revision 1.2
diff -u -p -r1.2 gencode.c
--- gencode.c	20 May 2001 15:40:27 -0000	1.2
+++ gencode.c	13 Aug 2002 07:39:52 -0000
@@ -1,6 +1,6 @@
 /* gencode.c -- Motorola 68HC11 & 68HC12 Emulator Generator
-   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
-   Written by Stephane Carrez (stcarrez@worldnet.fr)
+   Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Written by Stephane Carrez (stcarrez@nerim.fr)
 
 This file is part of GDB, GAS, and the GNU binutils.
 
@@ -284,6 +284,7 @@ cpu_set_ccr_Z (proc, dst16 == 0);\n\
   /* 68HC12 special instructions.  */
   { "bgnd",  "cpu_special (proc, M6812_BGND)" },
   { "call8", "cpu_special (proc, M6812_CALL)" },
+  { "call_ind", "cpu_special (proc, M6812_CALL_INDIRECT)" },
   { "dbcc8", "cpu_dbcc (proc)" },
   { "ediv",  "cpu_special (proc, M6812_EDIV)" },
   { "emul",  "{ uint32 src1 = (uint32) cpu_get_d (proc);\
@@ -384,7 +385,7 @@ struct m6811_opcode_def m6811_page1_opco
   { "page3", 0,		"page3",     1, 0x1a,  0,  0, CHG_NONE },
 
   /* After 'daa', the Z flag is undefined.  Mark it as changed.	 */
-  { "daa",  "a->a",	"daa8",	     1, 0x19,  2,  2, CHG_NZVC },
+  { "daa",  "",	        "daa8",	     1, 0x19,  2,  2, CHG_NZVC },
   { "aba",  "b,a->a",	"add8",	     1, 0x1b,  2,  2, CHG_HNZVC},
   { "bset", "(x),#->(x)","or8",	     3, 0x1c,  7,  7, CLR_V_CHG_NZ },
   { "bclr", "(x),#->(x)","bclr8",    3, 0x1d,  7,  7, CLR_V_CHG_NZ },
@@ -821,8 +822,8 @@ struct m6811_opcode_def m6812_page1_opco
   { "bvc",   "r",         0,         2, 0x28,  1,  3, CHG_NONE },
   { "bvs",   "r",         0,         2, 0x29,  1,  3, CHG_NONE },
 
-  { "call",  "()",        "call8",   4, 0x4a,  8,  8,  CHG_NONE },
-  { "call",  "[]",        "call8",   2, 0x4b,  8,  8,  CHG_NONE },
+  { "call",  "",          "call8",   4, 0x4a,  8,  8,  CHG_NONE },
+  { "call",  "",          "call_ind",2, 0x4b,  8,  8,  CHG_NONE },
 
   { "clr",   "->()",      "clr8",    3, 0x79,  3,  3,  SET_Z_CLR_NVC },
   { "clr",   "->[]",      "clr8",    2, 0x69,  2,  2,  SET_Z_CLR_NVC },
@@ -1977,8 +1978,11 @@ gen_cycle_table (FILE *fp, const char *n
   print (fp, 0, "};\n\n");
 }
 
+#define USE_SRC8 1
+#define USE_DST8 2
+
 void
-gen_function_entry (FILE *fp, const char *name)
+gen_function_entry (FILE *fp, const char *name, int locals)
 {
   /* Generate interpretor entry point.	*/
   print (fp, 0, "%s (proc)\n", name);
@@ -1988,7 +1992,10 @@ gen_function_entry (FILE *fp, const char
   /* Interpretor local variables.  */
   print (fp, indent_level, "unsigned char op;");
   print (fp, indent_level, "uint16 addr, src16, dst16;");
-  print (fp, indent_level, "uint8 src8, dst8;\n");
+  if (locals & USE_SRC8)
+    print (fp, indent_level, "uint8 src8;\n");
+  if (locals & USE_DST8)
+    print (fp, indent_level, "uint8 dst8;\n");
 }
 
 void
@@ -2050,14 +2057,14 @@ gen_interpreter (FILE *fp)
       gen_cycle_table (fp, "cycles_page4", m6811_page4_opcodes,
 		       TABLE_SIZE (m6811_page4_opcodes));
 
-      gen_function_entry (fp, "static void\ncpu_page3_interp");
+      gen_function_entry (fp, "static void\ncpu_page3_interp", 0);
       gen_interpreter_for_table (fp, indent_level,
 				 m6811_page3_opcodes,
 				 TABLE_SIZE(m6811_page3_opcodes),
 				 "cycles_page3");
       gen_function_close (fp);
   
-      gen_function_entry (fp, "static void\ncpu_page4_interp");
+      gen_function_entry (fp, "static void\ncpu_page4_interp", 0);
       gen_interpreter_for_table (fp, indent_level,
 				 m6811_page4_opcodes,
 				 TABLE_SIZE(m6811_page4_opcodes),
@@ -2065,7 +2072,8 @@ gen_interpreter (FILE *fp)
       gen_function_close (fp);
 
       /* Generate the page 2, 3 and 4 handlers.  */
-      gen_function_entry (fp, "static void\ncpu_page2_interp");
+      gen_function_entry (fp, "static void\ncpu_page2_interp",
+                          USE_SRC8 | USE_DST8);
       gen_interpreter_for_table (fp, indent_level,
 				 m6811_page2_opcodes,
 				 TABLE_SIZE(m6811_page2_opcodes),
@@ -2073,7 +2081,8 @@ gen_interpreter (FILE *fp)
       gen_function_close (fp);
 
       /* Generate the interpretor entry point.  */
-      gen_function_entry (fp, "void\ncpu_interp_m6811");
+      gen_function_entry (fp, "void\ncpu_interp_m6811",
+                          USE_SRC8 | USE_DST8);
 
       gen_interpreter_for_table (fp, indent_level, m6811_page1_opcodes,
 				 TABLE_SIZE(m6811_page1_opcodes),
@@ -2087,7 +2096,8 @@ gen_interpreter (FILE *fp)
       gen_cycle_table (fp, "cycles_page2", m6812_page2_opcodes,
 		       TABLE_SIZE (m6812_page2_opcodes));
 
-      gen_function_entry (fp, "static void\ncpu_page2_interp");
+      gen_function_entry (fp, "static void\ncpu_page2_interp",
+                          USE_SRC8 | USE_DST8);
       gen_interpreter_for_table (fp, indent_level,
 				 m6812_page2_opcodes,
 				 TABLE_SIZE(m6812_page2_opcodes),
@@ -2095,7 +2105,8 @@ gen_interpreter (FILE *fp)
       gen_function_close (fp);
 
       /* Generate the interpretor entry point.  */
-      gen_function_entry (fp, "void\ncpu_interp_m6812");
+      gen_function_entry (fp, "void\ncpu_interp_m6812",
+                          USE_SRC8 | USE_DST8);
 
       gen_interpreter_for_table (fp, indent_level, m6812_page1_opcodes,
 				 TABLE_SIZE(m6812_page1_opcodes),
Index: interp.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/interp.c,v
retrieving revision 1.8
diff -u -p -r1.8 interp.c
--- interp.c	7 Mar 2002 19:17:04 -0000	1.8
+++ interp.c	13 Aug 2002 07:39:52 -0000
@@ -1,6 +1,6 @@
 /* interp.c -- Simulator for Motorola 68HC11/68HC12
    Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-   Written by Stephane Carrez (stcarrez@worldnet.fr)
+   Written by Stephane Carrez (stcarrez@nerim.fr)
 
 This file is part of GDB, the GNU debugger.
 
@@ -468,16 +468,19 @@ sim_fetch_register (SIM_DESC sd, int rn,
 {
   sim_cpu *cpu;
   uint16 val;
+  int size = 2;
 
   cpu = STATE_CPU (sd, 0);
   switch (rn)
     {
     case A_REGNUM:
       val = cpu_get_a (cpu);
+      size = 1;
       break;
 
     case B_REGNUM:
       val = cpu_get_b (cpu);
+      size = 1;
       break;
 
     case D_REGNUM:
@@ -502,6 +505,12 @@ sim_fetch_register (SIM_DESC sd, int rn,
 
     case PSW_REGNUM:
       val = cpu_get_ccr (cpu);
+      size = 1;
+      break;
+
+    case PAGE_REGNUM:
+      val = cpu_get_page (cpu);
+      size = 1;
       break;
 
     default:
@@ -510,7 +519,7 @@ sim_fetch_register (SIM_DESC sd, int rn,
     }
   memory[0] = val >> 8;
   memory[1] = val & 0x0FF;
-  return 2;
+  return size;
 }
 
 int
@@ -533,11 +542,11 @@ sim_store_register (SIM_DESC sd, int rn,
 
     case A_REGNUM:
       cpu_set_a (cpu, val);
-      break;
+      return 1;
 
     case B_REGNUM:
       cpu_set_b (cpu, val);
-      break;
+      return 1;
 
     case X_REGNUM:
       cpu_set_x (cpu, val);
@@ -557,7 +566,11 @@ sim_store_register (SIM_DESC sd, int rn,
 
     case PSW_REGNUM:
       cpu_set_ccr (cpu, val);
-      break;
+      return 1;
+
+    case PAGE_REGNUM:
+      cpu_set_page (cpu, val);
+      return 1;
 
     default:
       break;
Index: m68hc11_sim.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/m68hc11_sim.c,v
retrieving revision 1.6
diff -u -p -r1.6 m68hc11_sim.c
--- m68hc11_sim.c	7 Mar 2002 19:17:04 -0000	1.6
+++ m68hc11_sim.c	13 Aug 2002 07:39:53 -0000
@@ -1,6 +1,6 @@
 /* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation
    Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-   Written by Stephane Carrez (stcarrez@worldnet.fr)
+   Written by Stephane Carrez (stcarrez@nerim.fr)
 
 This file is part of GDB, GAS, and the GNU binutils.
 
@@ -907,6 +907,60 @@ cpu_special (sim_cpu *cpu, enum M6811_Sp
       }
       break;
 
+    case M6812_CALL:
+      {
+        uint8 page;
+        uint16 addr;
+
+        addr = cpu_fetch16 (cpu);
+        page = cpu_fetch8 (cpu);
+
+        cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu));
+        cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu));
+
+        cpu_set_page (cpu, page);
+        cpu_set_pc (cpu, addr);
+      }
+      break;
+
+    case M6812_CALL_INDIRECT:
+      {
+        uint8 code;
+        uint16 addr;
+        uint8 page;
+
+        code = memory_read8 (cpu, cpu_get_pc (cpu));
+        /* Indirect addressing call has the page specified in the
+           memory location pointed to by the address.  */
+        if ((code & 0xE3) == 0xE3)
+          {
+            addr = cpu_get_indexed_operand_addr (cpu, 0);
+            page = memory_read8 (cpu, addr + 2);
+            addr = memory_read16 (cpu, addr);
+          }
+        else
+          {
+            /* Otherwise, page is in the opcode.  */
+            addr = cpu_get_indexed_operand16 (cpu, 0);
+            page = cpu_fetch8 (cpu);
+          }
+        cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu));
+        cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu));
+        cpu_set_page (cpu, page);
+        cpu_set_pc (cpu, addr);
+      }
+      break;
+
+    case M6812_RTC:
+      {
+        uint8 page = cpu_m68hc12_pop_uint8 (cpu);
+        uint16 addr = cpu_m68hc12_pop_uint16 (cpu);
+
+        cpu_set_page (cpu, page);
+        cpu_set_pc (cpu, addr);
+      }
+      break;
+      
     case M6812_ETBL:
     default:
       sim_engine_halt (CPU_STATE (cpu), cpu, NULL,
Index: sim-main.h
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/sim-main.h,v
retrieving revision 1.8
diff -u -p -r1.8 sim-main.h
--- sim-main.h	9 Jun 2002 15:45:48 -0000	1.8
+++ sim-main.h	13 Aug 2002 07:39:53 -0000
@@ -1,6 +1,6 @@
 /* sim-main.h -- Simulator for Motorola 68HC11 & 68HC12
    Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-   Written by Stephane Carrez (stcarrez@worldnet.fr)
+   Written by Stephane Carrez (stcarrez@nerim.fr)
 
 This file is part of GDB, the GNU debugger.
 
@@ -80,6 +80,7 @@ enum cpu_type
 #define B_REGNUM        6
 #define PSW_REGNUM 	7
 #define Z_REGNUM        8
+#define PAGE_REGNUM     9
 
 typedef struct m6811_regs {
     unsigned short      d;
@@ -88,6 +89,7 @@ typedef struct m6811_regs {
     unsigned short      sp;
     unsigned short      pc;
     unsigned char       ccr;
+  unsigned short      page;
 } m6811_regs;
 
 
@@ -126,6 +128,7 @@ enum M6811_Special
   /* 68HC12 instructions.  */
   M6812_BGND,
   M6812_CALL,
+  M6812_CALL_INDIRECT,
   M6812_IDIVS,
   M6812_EDIV,
   M6812_EDIVS,
@@ -232,6 +235,7 @@ struct _sim_cpu {
 #define cpu_get_sp(PROC)           ((PROC)->cpu_regs.sp)
 #define cpu_get_a(PROC)            ((PROC->cpu_regs.d >> 8) & 0x0FF)
 #define cpu_get_b(PROC)            ((PROC->cpu_regs.d) & 0x0FF)
+#define cpu_get_page(PROC)         (PROC->cpu_regs.page)
 
 /* 68HC12 specific and Motorola internal registers.  */
 #define cpu_get_tmp3(PROC)         (0)
@@ -240,10 +244,11 @@ struct _sim_cpu {
 #define cpu_set_d(PROC,VAL)        (((PROC)->cpu_regs.d) = (VAL))
 #define cpu_set_x(PROC,VAL)        (((PROC)->cpu_regs.ix) = (VAL))
 #define cpu_set_y(PROC,VAL)        (((PROC)->cpu_regs.iy) = (VAL))
+#define cpu_set_page(PROC,VAL)     ((PROC->cpu_regs.page) = (VAL))
 
 /* 68HC12 specific and Motorola internal registers.  */
 #define cpu_set_tmp3(PROC,VAL)     (0)
-#define cpu_set_tmp2(PROC,VAL)     (0)
+#define cpu_set_tmp2(PROC,VAL)     (void) (0)
 
 #if 0
 /* This is a function in m68hc11_sim.c to keep track of the frame.  */
@@ -287,11 +292,21 @@ extern void cpu_memory_exception (struct
                                   uint16 addr,
                                   const char *message);
 
+inline address_word
+phys_to_virt (sim_cpu *cpu, address_word addr)
+{
+  if (addr >= 0x8000 && addr < 0xc000)
+    return ((address_word) (addr) - 0x8000)
+      + (((address_word) cpu->cpu_regs.page) << 14) + 0x01000000;
+  else
+    return (address_word) (addr);
+}
+
 inline uint8
 memory_read8 (sim_cpu *cpu, uint16 addr)
 {
   uint8 val;
-  
+
   if (sim_core_read_buffer (CPU_STATE (cpu), cpu, 0, &val, addr, 1) != 1)
     {
       cpu_memory_exception (cpu, SIM_SIGSEGV, addr,
@@ -314,7 +329,7 @@ inline uint16
 memory_read16 (sim_cpu *cpu, uint16 addr)
 {
   uint8 b[2];
-  
+
   if (sim_core_read_buffer (CPU_STATE (cpu), cpu, 0, b, addr, 2) != 2)
     {
       cpu_memory_exception (cpu, SIM_SIGSEGV, addr,
@@ -523,6 +538,11 @@ extern void cpu_info (SIM_DESC sd, sim_c
 
 extern int cpu_initialize (SIM_DESC sd, sim_cpu *cpu);
 
+/* Returns the address of a 68HC12 indexed operand.
+   Pre and post modifications are handled on the source register.  */
+extern uint16 cpu_get_indexed_operand_addr (sim_cpu* cpu, int restrict);
+
+extern void cpu_return (sim_cpu *cpu);
 extern void cpu_set_sp (sim_cpu *cpu, uint16 val);
 extern int cpu_reset (sim_cpu *cpu);
 extern int cpu_restart (sim_cpu *cpu);

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