* m68hc11_sim.c (cpu_special): Handle call and rtc instructions.
authorStephane Carrez <stcarrez@nerim.fr>
Tue, 13 Aug 2002 07:46:09 +0000 (07:46 +0000)
committerStephane Carrez <stcarrez@nerim.fr>
Tue, 13 Aug 2002 07:46:09 +0000 (07:46 +0000)
* 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.

sim/m68hc11/ChangeLog
sim/m68hc11/gencode.c
sim/m68hc11/interp.c
sim/m68hc11/m68hc11_sim.c
sim/m68hc11/sim-main.h

index 7c08019283bdc27b9e15cd27dc42f482e6bd46d3..95047da6f2f7c84a190851e7ee8d735cd4cb33f9 100644 (file)
@@ -1,3 +1,19 @@
+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.
+
 2002-06-16  Andrew Cagney  <ac131313@redhat.com>
 
        * configure: Regenerated to track ../common/aclocal.m4 changes.
index 8c32e3e16497bff6b2a3041d0e2a0cbb54ef71ca..c602656a6591ab3f833d67fee6b513aa77e96a8e 100644 (file)
@@ -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_opcodes[] = {
   { "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_opcodes[] = {
   { "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 *name,
   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 *name)
   /* 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 ee2acef698ce67130771d3d3a3a8a4be68ba1339..03b6db7373153f98b76a98f069da620750b1f575 100644 (file)
@@ -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, unsigned char *memory, int length)
 {
   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, unsigned char *memory, int length)
 
     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, unsigned char *memory, int length)
     }
   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, unsigned char *memory, int length)
 
     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, unsigned char *memory, int length)
 
     case PSW_REGNUM:
       cpu_set_ccr (cpu, val);
-      break;
+      return 1;
+
+    case PAGE_REGNUM:
+      cpu_set_page (cpu, val);
+      return 1;
 
     default:
       break;
index d9fb807e937367cb4ec0913ead079173d4d6bbdf..fe5985f8f1ccabb1587581079bdaf6c701db691f 100644 (file)
@@ -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_Special special)
       }
       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 75c3b5b845155e33933ec7948fffeaad537073d0..c8933a0791f13d7e02543063f1665f96ba4938ec 100644 (file)
@@ -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 _sim_cpu *proc,
                                   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_cpu *proc);
 
 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);