/* 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.
/* 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);\
{ "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 },
{ "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 },
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);
/* 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
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),
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),
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),
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),
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),
/* 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.
}
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,
/* 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.
#define B_REGNUM 6
#define PSW_REGNUM 7
#define Z_REGNUM 8
+#define PAGE_REGNUM 9
typedef struct m6811_regs {
unsigned short d;
unsigned short sp;
unsigned short pc;
unsigned char ccr;
+ unsigned short page;
} m6811_regs;
/* 68HC12 instructions. */
M6812_BGND,
M6812_CALL,
+ M6812_CALL_INDIRECT,
M6812_IDIVS,
M6812_EDIV,
M6812_EDIVS,
#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)
#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. */
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,
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,
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);