diff options
Diffstat (limited to 'sim/m68hc11/m68hc11_sim.c')
-rw-r--r-- | sim/m68hc11/m68hc11_sim.c | 1071 |
1 files changed, 0 insertions, 1071 deletions
diff --git a/sim/m68hc11/m68hc11_sim.c b/sim/m68hc11/m68hc11_sim.c deleted file mode 100644 index 444147b..0000000 --- a/sim/m68hc11/m68hc11_sim.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation - Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. - Written by Stephane Carrez (stcarrez@nerim.fr) - -This file is part of GDB, GAS, and the GNU binutils. - -GDB, GAS, and the GNU binutils are free software; you can redistribute -them and/or modify them under the terms of the GNU General Public -License as published by the Free Software Foundation; either version -1, or (at your option) any later version. - -GDB, GAS, and the GNU binutils are distributed in the hope that they -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 file; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "sim-main.h" -#include "sim-assert.h" -#include "sim-module.h" -#include "sim-options.h" - -enum { - OPTION_CPU_RESET = OPTION_START, - OPTION_EMUL_OS, - OPTION_CPU_CONFIG, - OPTION_CPU_BOOTSTRAP, - OPTION_CPU_MODE -}; - -static DECLARE_OPTION_HANDLER (cpu_option_handler); - -static const OPTION cpu_options[] = -{ - { {"cpu-reset", no_argument, NULL, OPTION_CPU_RESET }, - '\0', NULL, "Reset the CPU", - cpu_option_handler }, - - { {"emulos", no_argument, NULL, OPTION_EMUL_OS }, - '\0', NULL, "Emulate some OS system calls (read, write, ...)", - cpu_option_handler }, - - { {"cpu-config", required_argument, NULL, OPTION_CPU_CONFIG }, - '\0', NULL, "Specify the initial CPU configuration register", - cpu_option_handler }, - - { {"bootstrap", no_argument, NULL, OPTION_CPU_BOOTSTRAP }, - '\0', NULL, "Start the processing in bootstrap mode", - cpu_option_handler }, - - { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL } -}; - - -static SIM_RC -cpu_option_handler (SIM_DESC sd, sim_cpu *cpu, - int opt, char *arg, int is_command) -{ - int val; - - cpu = STATE_CPU (sd, 0); - switch (opt) - { - case OPTION_CPU_RESET: - sim_board_reset (sd); - break; - - case OPTION_EMUL_OS: - cpu->cpu_emul_syscall = 1; - break; - - case OPTION_CPU_CONFIG: - if (sscanf(arg, "0x%x", &val) == 1 - || sscanf(arg, "%d", &val) == 1) - { - cpu->cpu_config = val; - cpu->cpu_use_local_config = 1; - } - else - cpu->cpu_use_local_config = 0; - break; - - case OPTION_CPU_BOOTSTRAP: - cpu->cpu_start_mode = "bootstrap"; - break; - - case OPTION_CPU_MODE: - break; - } - - return SIM_RC_OK; -} - - -void -cpu_call (sim_cpu *cpu, uint16 addr) -{ - - cpu_set_pc (cpu, addr); -} - -void -cpu_return (sim_cpu *cpu) -{ -} - -/* Set the stack pointer and re-compute the current frame. */ -void -cpu_set_sp (sim_cpu *cpu, uint16 val) -{ - cpu->cpu_regs.sp = val; -} - -uint16 -cpu_get_reg (sim_cpu* cpu, uint8 reg) -{ - switch (reg) - { - case 0: - return cpu_get_x (cpu); - - case 1: - return cpu_get_y (cpu); - - case 2: - return cpu_get_sp (cpu); - - case 3: - return cpu_get_pc (cpu); - - default: - return 0; - } -} - -uint16 -cpu_get_src_reg (sim_cpu* cpu, uint8 reg) -{ - switch (reg) - { - case 0: - return cpu_get_a (cpu); - - case 1: - return cpu_get_b (cpu); - - case 2: - return cpu_get_ccr (cpu); - - case 3: - return cpu_get_tmp3 (cpu); - - case 4: - return cpu_get_d (cpu); - - case 5: - return cpu_get_x (cpu); - - case 6: - return cpu_get_y (cpu); - - case 7: - return cpu_get_sp (cpu); - - default: - return 0; - } -} - -void -cpu_set_dst_reg (sim_cpu* cpu, uint8 reg, uint16 val) -{ - switch (reg) - { - case 0: - cpu_set_a (cpu, val); - break; - - case 1: - cpu_set_b (cpu, val); - break; - - case 2: - cpu_set_ccr (cpu, val); - break; - - case 3: - cpu_set_tmp2 (cpu, val); - break; - - case 4: - cpu_set_d (cpu, val); - break; - - case 5: - cpu_set_x (cpu, val); - break; - - case 6: - cpu_set_y (cpu, val); - break; - - case 7: - cpu_set_sp (cpu, val); - break; - - default: - break; - } -} - -void -cpu_set_reg (sim_cpu* cpu, uint8 reg, uint16 val) -{ - switch (reg) - { - case 0: - cpu_set_x (cpu, val); - break; - - case 1: - cpu_set_y (cpu, val); - break; - - case 2: - cpu_set_sp (cpu, val); - break; - - case 3: - cpu_set_pc (cpu, val); - break; - - default: - break; - } -} - -/* Returns the address of a 68HC12 indexed operand. - Pre and post modifications are handled on the source register. */ -uint16 -cpu_get_indexed_operand_addr (sim_cpu* cpu, int restrict) -{ - uint8 reg; - uint16 sval; - uint16 addr; - uint8 code; - - code = cpu_fetch8 (cpu); - - /* n,r with 5-bit signed constant. */ - if ((code & 0x20) == 0) - { - reg = (code >> 6) & 3; - sval = (code & 0x1f); - if (code & 0x10) - sval |= 0xfff0; - - addr = cpu_get_reg (cpu, reg); - addr += sval; - } - - /* Auto pre/post increment/decrement. */ - else if ((code & 0xc0) != 0xc0) - { - reg = (code >> 6) & 3; - sval = (code & 0x0f); - if (sval & 0x8) - { - sval |= 0xfff0; - } - else - { - sval = sval + 1; - } - addr = cpu_get_reg (cpu, reg); - cpu_set_reg (cpu, reg, addr + sval); - if ((code & 0x10) == 0) - { - addr += sval; - } - } - - /* [n,r] 16-bits offset indexed indirect. */ - else if ((code & 0x07) == 3) - { - if (restrict) - { - return 0; - } - reg = (code >> 3) & 0x03; - addr = cpu_get_reg (cpu, reg); - addr += cpu_fetch16 (cpu); - addr = memory_read16 (cpu, addr); - cpu_add_cycles (cpu, 1); - } - else if ((code & 0x4) == 0) - { - if (restrict) - { - return 0; - } - reg = (code >> 3) & 0x03; - addr = cpu_get_reg (cpu, reg); - if (code & 0x2) - { - sval = cpu_fetch16 (cpu); - cpu_add_cycles (cpu, 1); - } - else - { - sval = cpu_fetch8 (cpu); - if (code & 0x1) - sval |= 0xff00; - cpu_add_cycles (cpu, 1); - } - addr += sval; - } - else - { - reg = (code >> 3) & 0x03; - addr = cpu_get_reg (cpu, reg); - switch (code & 3) - { - case 0: - addr += cpu_get_a (cpu); - break; - case 1: - addr += cpu_get_b (cpu); - break; - case 2: - addr += cpu_get_d (cpu); - break; - case 3: - default: - addr += cpu_get_d (cpu); - addr = memory_read16 (cpu, addr); - cpu_add_cycles (cpu, 1); - break; - } - } - - return addr; -} - -uint8 -cpu_get_indexed_operand8 (sim_cpu* cpu, int restrict) -{ - uint16 addr; - - addr = cpu_get_indexed_operand_addr (cpu, restrict); - return memory_read8 (cpu, addr); -} - -uint16 -cpu_get_indexed_operand16 (sim_cpu* cpu, int restrict) -{ - uint16 addr; - - addr = cpu_get_indexed_operand_addr (cpu, restrict); - return memory_read16 (cpu, addr); -} - -void -cpu_move8 (sim_cpu *cpu, uint8 code) -{ - uint8 src; - uint16 addr; - - switch (code) - { - case 0x0b: - src = cpu_fetch8 (cpu); - addr = cpu_fetch16 (cpu); - break; - - case 0x08: - addr = cpu_get_indexed_operand_addr (cpu, 1); - src = cpu_fetch8 (cpu); - break; - - case 0x0c: - addr = cpu_fetch16 (cpu); - src = memory_read8 (cpu, addr); - addr = cpu_fetch16 (cpu); - break; - - case 0x09: - addr = cpu_get_indexed_operand_addr (cpu, 1); - src = memory_read8 (cpu, cpu_fetch16 (cpu)); - break; - - case 0x0d: - src = cpu_get_indexed_operand8 (cpu, 1); - addr = cpu_fetch16 (cpu); - break; - - case 0x0a: - src = cpu_get_indexed_operand8 (cpu, 1); - addr = cpu_get_indexed_operand_addr (cpu, 1); - break; - - default: - sim_engine_abort (CPU_STATE (cpu), cpu, 0, - "Invalid code 0x%0x -- internal error?", code); - return; - } - memory_write8 (cpu, addr, src); -} - -void -cpu_move16 (sim_cpu *cpu, uint8 code) -{ - uint16 src; - uint16 addr; - - switch (code) - { - case 0x03: - src = cpu_fetch16 (cpu); - addr = cpu_fetch16 (cpu); - break; - - case 0x00: - addr = cpu_get_indexed_operand_addr (cpu, 1); - src = cpu_fetch16 (cpu); - break; - - case 0x04: - addr = cpu_fetch16 (cpu); - src = memory_read16 (cpu, addr); - addr = cpu_fetch16 (cpu); - break; - - case 0x01: - addr = cpu_get_indexed_operand_addr (cpu, 1); - src = memory_read16 (cpu, cpu_fetch16 (cpu)); - break; - - case 0x05: - src = cpu_get_indexed_operand16 (cpu, 1); - addr = cpu_fetch16 (cpu); - break; - - case 0x02: - src = cpu_get_indexed_operand16 (cpu, 1); - addr = cpu_get_indexed_operand_addr (cpu, 1); - break; - - default: - sim_engine_abort (CPU_STATE (cpu), cpu, 0, - "Invalid code 0x%0x -- internal error?", code); - return; - } - memory_write16 (cpu, addr, src); -} - -int -cpu_initialize (SIM_DESC sd, sim_cpu *cpu) -{ - sim_add_option_table (sd, 0, cpu_options); - - memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs)); - - cpu->cpu_absolute_cycle = 0; - cpu->cpu_current_cycle = 0; - cpu->cpu_emul_syscall = 1; - cpu->cpu_running = 1; - cpu->cpu_stop_on_interrupt = 0; - cpu->cpu_frequency = 8 * 1000 * 1000; - cpu->cpu_use_elf_start = 0; - cpu->cpu_elf_start = 0; - cpu->cpu_use_local_config = 0; - cpu->bank_start = 0; - cpu->bank_end = 0; - cpu->bank_shift = 0; - cpu->cpu_config = M6811_NOSEC | M6811_NOCOP | M6811_ROMON | - M6811_EEON; - interrupts_initialize (sd, cpu); - - cpu->cpu_is_initialized = 1; - return 0; -} - - -/* Reinitialize the processor after a reset. */ -int -cpu_reset (sim_cpu *cpu) -{ - /* Initialize the config register. - It is only initialized at reset time. */ - memset (cpu->ios, 0, sizeof (cpu->ios)); - if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11) - cpu->ios[M6811_INIT] = 0x1; - else - cpu->ios[M6811_INIT] = 0; - - /* Output compare registers set to 0xFFFF. */ - cpu->ios[M6811_TOC1_H] = 0xFF; - cpu->ios[M6811_TOC1_L] = 0xFF; - cpu->ios[M6811_TOC2_H] = 0xFF; - cpu->ios[M6811_TOC2_L] = 0xFF; - cpu->ios[M6811_TOC3_H] = 0xFF; - cpu->ios[M6811_TOC4_L] = 0xFF; - cpu->ios[M6811_TOC5_H] = 0xFF; - cpu->ios[M6811_TOC5_L] = 0xFF; - - /* Setup the processor registers. */ - memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs)); - cpu->cpu_absolute_cycle = 0; - cpu->cpu_current_cycle = 0; - cpu->cpu_is_initialized = 0; - - /* Reset interrupts. */ - interrupts_reset (&cpu->cpu_interrupts); - - /* Reinitialize the CPU operating mode. */ - cpu->ios[M6811_HPRIO] = cpu->cpu_mode; - return 0; -} - -/* Reinitialize the processor after a reset. */ -int -cpu_restart (sim_cpu *cpu) -{ - uint16 addr; - - /* Get CPU starting address depending on the CPU mode. */ - if (cpu->cpu_use_elf_start == 0) - { - switch ((cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA)) - { - /* Single Chip */ - default: - case 0 : - addr = memory_read16 (cpu, 0xFFFE); - break; - - /* Expanded Multiplexed */ - case M6811_MDA: - addr = memory_read16 (cpu, 0xFFFE); - break; - - /* Special Bootstrap */ - case M6811_SMOD: - addr = 0; - break; - - /* Factory Test */ - case M6811_MDA | M6811_SMOD: - addr = memory_read16 (cpu, 0xFFFE); - break; - } - } - else - { - addr = cpu->cpu_elf_start; - } - - /* Setup the processor registers. */ - cpu->cpu_insn_pc = addr; - cpu->cpu_regs.pc = addr; - cpu->cpu_regs.ccr = M6811_X_BIT | M6811_I_BIT | M6811_S_BIT; - cpu->cpu_absolute_cycle = 0; - cpu->cpu_is_initialized = 1; - cpu->cpu_current_cycle = 0; - - cpu_call (cpu, addr); - - return 0; -} - -void -print_io_reg_desc (SIM_DESC sd, io_reg_desc *desc, int val, int mode) -{ - while (desc->mask) - { - if (val & desc->mask) - sim_io_printf (sd, "%s", - mode == 0 ? desc->short_name : desc->long_name); - desc++; - } -} - -void -print_io_byte (SIM_DESC sd, const char *name, io_reg_desc *desc, - uint8 val, uint16 addr) -{ - sim_io_printf (sd, " %-9.9s @ 0x%04x 0x%02x ", name, addr, val); - if (desc) - print_io_reg_desc (sd, desc, val, 0); -} - -void -print_io_word (SIM_DESC sd, const char *name, io_reg_desc *desc, - uint16 val, uint16 addr) -{ - sim_io_printf (sd, " %-9.9s @ 0x%04x 0x%04x ", name, addr, val); - if (desc) - print_io_reg_desc (sd, desc, val, 0); -} - -void -cpu_ccr_update_tst8 (sim_cpu *proc, uint8 val) -{ - cpu_set_ccr_V (proc, 0); - cpu_set_ccr_N (proc, val & 0x80 ? 1 : 0); - cpu_set_ccr_Z (proc, val == 0 ? 1 : 0); -} - - -uint16 -cpu_fetch_relbranch (sim_cpu *cpu) -{ - uint16 addr = (uint16) cpu_fetch8 (cpu); - - if (addr & 0x0080) - { - addr |= 0xFF00; - } - addr += cpu->cpu_regs.pc; - return addr; -} - -uint16 -cpu_fetch_relbranch16 (sim_cpu *cpu) -{ - uint16 addr = cpu_fetch16 (cpu); - - addr += cpu->cpu_regs.pc; - return addr; -} - -/* Push all the CPU registers (when an interruption occurs). */ -void -cpu_push_all (sim_cpu *cpu) -{ - if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11) - { - cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.pc); - cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.iy); - cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.ix); - cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.d); - cpu_m68hc11_push_uint8 (cpu, cpu->cpu_regs.ccr); - } - else - { - cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.pc); - cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.iy); - cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.ix); - cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.d); - cpu_m68hc12_push_uint8 (cpu, cpu->cpu_regs.ccr); - } -} - -/* Simulation of the dbcc/ibcc/tbcc 68HC12 conditional branch operations. */ -void -cpu_dbcc (sim_cpu* cpu) -{ - uint8 code; - uint16 addr; - uint16 inc; - uint16 reg; - - code = cpu_fetch8 (cpu); - switch (code & 0xc0) - { - case 0x80: /* ibcc */ - inc = 1; - break; - case 0x40: /* tbcc */ - inc = 0; - break; - case 0: /* dbcc */ - inc = -1; - break; - default: - abort (); - break; - } - - addr = cpu_fetch8 (cpu); - if (code & 0x10) - addr |= 0xff00; - - addr += cpu_get_pc (cpu); - reg = cpu_get_src_reg (cpu, code & 0x07); - reg += inc; - - /* Branch according to register value. */ - if ((reg != 0 && (code & 0x20)) || (reg == 0 && !(code & 0x20))) - { - cpu_set_pc (cpu, addr); - } - cpu_set_dst_reg (cpu, code & 0x07, reg); -} - -void -cpu_exg (sim_cpu* cpu, uint8 code) -{ - uint8 r1, r2; - uint16 src1; - uint16 src2; - - r1 = (code >> 4) & 0x07; - r2 = code & 0x07; - if (code & 0x80) - { - src1 = cpu_get_src_reg (cpu, r1); - src2 = cpu_get_src_reg (cpu, r2); - if (r2 == 1 || r2 == 2) - src2 |= 0xff00; - - cpu_set_dst_reg (cpu, r2, src1); - cpu_set_dst_reg (cpu, r1, src2); - } - else - { - src1 = cpu_get_src_reg (cpu, r1); - - /* Sign extend the 8-bit registers (A, B, CCR). */ - if ((r1 == 0 || r1 == 1 || r1 == 2) && (src1 & 0x80)) - src1 |= 0xff00; - - cpu_set_dst_reg (cpu, r2, src1); - } -} - -/* Handle special instructions. */ -void -cpu_special (sim_cpu *cpu, enum M6811_Special special) -{ - switch (special) - { - case M6811_RTI: - { - uint8 ccr; - - ccr = cpu_m68hc11_pop_uint8 (cpu); - cpu_set_ccr (cpu, ccr); - cpu_set_d (cpu, cpu_m68hc11_pop_uint16 (cpu)); - cpu_set_x (cpu, cpu_m68hc11_pop_uint16 (cpu)); - cpu_set_y (cpu, cpu_m68hc11_pop_uint16 (cpu)); - cpu_set_pc (cpu, cpu_m68hc11_pop_uint16 (cpu)); - cpu_return (cpu); - break; - } - - case M6812_RTI: - { - uint8 ccr; - - ccr = cpu_m68hc12_pop_uint8 (cpu); - cpu_set_ccr (cpu, ccr); - cpu_set_d (cpu, cpu_m68hc12_pop_uint16 (cpu)); - cpu_set_x (cpu, cpu_m68hc12_pop_uint16 (cpu)); - cpu_set_y (cpu, cpu_m68hc12_pop_uint16 (cpu)); - cpu_set_pc (cpu, cpu_m68hc12_pop_uint16 (cpu)); - cpu_return (cpu); - break; - } - - case M6811_WAI: - /* In the ELF-start mode, we are in a special mode where - the WAI corresponds to an exit. */ - if (cpu->cpu_use_elf_start) - { - cpu_set_pc (cpu, cpu->cpu_insn_pc); - sim_engine_halt (CPU_STATE (cpu), cpu, - NULL, NULL_CIA, sim_exited, - cpu_get_d (cpu)); - return; - } - /* SCz: not correct... */ - cpu_push_all (cpu); - break; - - case M6811_SWI: - interrupts_raise (&cpu->cpu_interrupts, M6811_INT_SWI); - interrupts_process (&cpu->cpu_interrupts); - break; - - case M6811_EMUL_SYSCALL: - case M6811_ILLEGAL: - if (cpu->cpu_emul_syscall) - { - uint8 op = memory_read8 (cpu, - cpu_get_pc (cpu) - 1); - if (op == 0x41) - { - cpu_set_pc (cpu, cpu->cpu_insn_pc); - sim_engine_halt (CPU_STATE (cpu), cpu, - NULL, NULL_CIA, sim_exited, - cpu_get_d (cpu)); - return; - } - else - { - emul_os (op, cpu); - } - return; - } - - interrupts_raise (&cpu->cpu_interrupts, M6811_INT_ILLEGAL); - interrupts_process (&cpu->cpu_interrupts); - break; - - case M6811_TEST: - case M6812_BGND: - { - SIM_DESC sd; - - sd = CPU_STATE (cpu); - - /* Breakpoint instruction if we are under gdb. */ - if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG) - { - cpu->cpu_regs.pc --; - sim_engine_halt (CPU_STATE (cpu), cpu, - 0, cpu_get_pc (cpu), sim_stopped, - SIM_SIGTRAP); - } - /* else this is a nop but not in test factory mode. */ - break; - } - - case M6812_IDIVS: - { - int32 src1 = (int16) cpu_get_d (cpu); - int32 src2 = (int16) cpu_get_x (cpu); - - if (src2 == 0) - { - cpu_set_ccr_C (cpu, 1); - } - else - { - cpu_set_d (cpu, src1 % src2); - src1 = src1 / src2; - cpu_set_x (cpu, src1); - cpu_set_ccr_C (cpu, 0); - cpu_set_ccr_Z (cpu, src1 == 0); - cpu_set_ccr_N (cpu, src1 & 0x8000); - cpu_set_ccr_V (cpu, src1 >= 32768 || src1 < -32768); - } - } - break; - - case M6812_EDIV: - { - uint32 src1 = (uint32) cpu_get_x (cpu); - uint32 src2 = (uint32) (cpu_get_y (cpu) << 16) - | (uint32) (cpu_get_d (cpu)); - - if (src1 == 0) - { - cpu_set_ccr_C (cpu, 1); - } - else - { - cpu_set_ccr_C (cpu, 0); - cpu_set_d (cpu, src2 % src1); - src2 = src2 / src1; - cpu_set_y (cpu, src2); - cpu_set_ccr_Z (cpu, src2 == 0); - cpu_set_ccr_N (cpu, (src2 & 0x8000) != 0); - cpu_set_ccr_V (cpu, (src2 & 0xffff0000) != 0); - } - } - break; - - case M6812_EDIVS: - { - int32 src1 = (int16) cpu_get_x (cpu); - int32 src2 = (uint32) (cpu_get_y (cpu) << 16) - | (uint32) (cpu_get_d (cpu)); - - if (src1 == 0) - { - cpu_set_ccr_C (cpu, 1); - } - else - { - cpu_set_ccr_C (cpu, 0); - cpu_set_d (cpu, src2 % src1); - src2 = src2 / src1; - cpu_set_y (cpu, src2); - cpu_set_ccr_Z (cpu, src2 == 0); - cpu_set_ccr_N (cpu, (src2 & 0x8000) != 0); - cpu_set_ccr_V (cpu, src2 > 32767 || src2 < -32768); - } - } - break; - - case M6812_EMULS: - { - int32 src1, src2; - - src1 = (int16) cpu_get_d (cpu); - src2 = (int16) cpu_get_y (cpu); - src1 = src1 * src2; - cpu_set_d (cpu, src1 & 0x0ffff); - cpu_set_y (cpu, src1 >> 16); - cpu_set_ccr_Z (cpu, src1 == 0); - cpu_set_ccr_N (cpu, (src1 & 0x80000000) != 0); - cpu_set_ccr_C (cpu, (src1 & 0x00008000) != 0); - } - break; - - case M6812_EMACS: - { - int32 src1, src2; - uint16 addr; - - addr = cpu_fetch16 (cpu); - src1 = (int16) memory_read16 (cpu, cpu_get_x (cpu)); - src2 = (int16) memory_read16 (cpu, cpu_get_y (cpu)); - src1 = src1 * src2; - src2 = (((uint32) memory_read16 (cpu, addr)) << 16) - | (uint32) memory_read16 (cpu, addr + 2); - - memory_write16 (cpu, addr, (src1 + src2) >> 16); - memory_write16 (cpu, addr + 2, (src1 + src2)); - - - } - 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, - cpu_get_pc (cpu), sim_stopped, - SIM_SIGILL); - break; - } -} - - -void -cpu_single_step (sim_cpu *cpu) -{ - cpu->cpu_current_cycle = 0; - cpu->cpu_insn_pc = cpu_get_pc (cpu); - - /* Handle the pending interrupts. If an interrupt is handled, - treat this as an single step. */ - if (interrupts_process (&cpu->cpu_interrupts)) - { - cpu->cpu_absolute_cycle += cpu->cpu_current_cycle; - return; - } - - /* printf("PC = 0x%04x\n", cpu_get_pc (cpu));*/ - cpu->cpu_interpretor (cpu); - cpu->cpu_absolute_cycle += cpu->cpu_current_cycle; -} - -/* VARARGS */ -void -sim_memory_error (sim_cpu *cpu, SIM_SIGNAL excep, - uint16 addr, const char *message, ...) -{ - char buf[1024]; - va_list args; - - va_start (args, message); - vsprintf (buf, message, args); - va_end (args); - - sim_io_printf (CPU_STATE (cpu), "%s\n", buf); - cpu_memory_exception (cpu, excep, addr, buf); -} - - -void -cpu_memory_exception (sim_cpu *cpu, SIM_SIGNAL excep, - uint16 addr, const char *message) -{ - if (cpu->cpu_running == 0) - return; - - cpu_set_pc (cpu, cpu->cpu_insn_pc); - sim_engine_halt (CPU_STATE (cpu), cpu, NULL, - cpu_get_pc (cpu), sim_stopped, excep); - -#if 0 - cpu->mem_exception = excep; - cpu->fault_addr = addr; - cpu->fault_msg = strdup (message); - - if (cpu->cpu_use_handler) - { - longjmp (&cpu->cpu_exception_handler, 1); - } - (* cpu->callback->printf_filtered) - (cpu->callback, "Fault at 0x%04x: %s\n", addr, message); -#endif -} - -void -cpu_info (SIM_DESC sd, sim_cpu *cpu) -{ - sim_io_printf (sd, "CPU info:\n"); - sim_io_printf (sd, " Absolute cycle: %s\n", - cycle_to_string (cpu, cpu->cpu_absolute_cycle, - PRINT_TIME | PRINT_CYCLE)); - - sim_io_printf (sd, " Syscall emulation: %s\n", - cpu->cpu_emul_syscall ? "yes, via 0xcd <n>" : "no"); - sim_io_printf (sd, " Memory errors detection: %s\n", - cpu->cpu_check_memory ? "yes" : "no"); - sim_io_printf (sd, " Stop on interrupt: %s\n", - cpu->cpu_stop_on_interrupt ? "yes" : "no"); -} - |