📄 m68hc11_sim.c
字号:
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;}voidprint_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++; }}voidprint_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);}voidprint_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);}voidcpu_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);}uint16cpu_fetch_relbranch (sim_cpu *cpu){ uint16 addr = (uint16) cpu_fetch8 (cpu); if (addr & 0x0080) { addr |= 0xFF00; } addr += cpu->cpu_regs.pc; return addr;}uint16cpu_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). */voidcpu_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. */voidcpu_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);}voidcpu_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. */voidcpu_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; }}voidcpu_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 */voidsim_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);}voidcpu_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}voidcpu_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");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -