1 /* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation
2 Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Written by Stephane Carrez (stcarrez@nerim.fr)
5 This file is part of GDB, GAS, and the GNU binutils.
7 GDB, GAS, and the GNU binutils are free software; you can redistribute
8 them and/or modify them under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either version
10 1, or (at your option) any later version.
12 GDB, GAS, and the GNU binutils are distributed in the hope that they
13 will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this file; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "sim-assert.h"
23 #include "sim-module.h"
24 #include "sim-options.h"
27 OPTION_CPU_RESET
= OPTION_START
,
34 static DECLARE_OPTION_HANDLER (cpu_option_handler
);
36 static const OPTION cpu_options
[] =
38 { {"cpu-reset", no_argument
, NULL
, OPTION_CPU_RESET
},
39 '\0', NULL
, "Reset the CPU",
42 { {"emulos", no_argument
, NULL
, OPTION_EMUL_OS
},
43 '\0', NULL
, "Emulate some OS system calls (read, write, ...)",
46 { {"cpu-config", required_argument
, NULL
, OPTION_CPU_CONFIG
},
47 '\0', NULL
, "Specify the initial CPU configuration register",
50 { {"bootstrap", no_argument
, NULL
, OPTION_CPU_BOOTSTRAP
},
51 '\0', NULL
, "Start the processing in bootstrap mode",
54 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
59 cpu_option_handler (SIM_DESC sd
, sim_cpu
*cpu
,
60 int opt
, char *arg
, int is_command
)
64 cpu
= STATE_CPU (sd
, 0);
67 case OPTION_CPU_RESET
:
72 cpu
->cpu_emul_syscall
= 1;
75 case OPTION_CPU_CONFIG
:
76 if (sscanf(arg
, "0x%x", &val
) == 1
77 || sscanf(arg
, "%d", &val
) == 1)
79 cpu
->cpu_config
= val
;
80 cpu
->cpu_use_local_config
= 1;
83 cpu
->cpu_use_local_config
= 0;
86 case OPTION_CPU_BOOTSTRAP
:
87 cpu
->cpu_start_mode
= "bootstrap";
99 cpu_call (sim_cpu
*cpu
, uint16 addr
)
102 cpu_set_pc (cpu
, addr
);
106 cpu_return (sim_cpu
*cpu
)
110 /* Set the stack pointer and re-compute the current frame. */
112 cpu_set_sp (sim_cpu
*cpu
, uint16 val
)
114 cpu
->cpu_regs
.sp
= val
;
118 cpu_get_reg (sim_cpu
* cpu
, uint8 reg
)
123 return cpu_get_x (cpu
);
126 return cpu_get_y (cpu
);
129 return cpu_get_sp (cpu
);
132 return cpu_get_pc (cpu
);
140 cpu_get_src_reg (sim_cpu
* cpu
, uint8 reg
)
145 return cpu_get_a (cpu
);
148 return cpu_get_b (cpu
);
151 return cpu_get_ccr (cpu
);
154 return cpu_get_tmp3 (cpu
);
157 return cpu_get_d (cpu
);
160 return cpu_get_x (cpu
);
163 return cpu_get_y (cpu
);
166 return cpu_get_sp (cpu
);
174 cpu_set_dst_reg (sim_cpu
* cpu
, uint8 reg
, uint16 val
)
179 cpu_set_a (cpu
, val
);
183 cpu_set_b (cpu
, val
);
187 cpu_set_ccr (cpu
, val
);
191 cpu_set_tmp2 (cpu
, val
);
195 cpu_set_d (cpu
, val
);
199 cpu_set_x (cpu
, val
);
203 cpu_set_y (cpu
, val
);
207 cpu_set_sp (cpu
, val
);
216 cpu_set_reg (sim_cpu
* cpu
, uint8 reg
, uint16 val
)
221 cpu_set_x (cpu
, val
);
225 cpu_set_y (cpu
, val
);
229 cpu_set_sp (cpu
, val
);
233 cpu_set_pc (cpu
, val
);
241 /* Returns the address of a 68HC12 indexed operand.
242 Pre and post modifications are handled on the source register. */
244 cpu_get_indexed_operand_addr (sim_cpu
* cpu
, int restrict
)
251 code
= cpu_fetch8 (cpu
);
253 /* n,r with 5-bit signed constant. */
254 if ((code
& 0x20) == 0)
256 reg
= (code
>> 6) & 3;
257 sval
= (code
& 0x1f);
261 addr
= cpu_get_reg (cpu
, reg
);
265 /* Auto pre/post increment/decrement. */
266 else if ((code
& 0xc0) != 0xc0)
268 reg
= (code
>> 6) & 3;
269 sval
= (code
& 0x0f);
278 addr
= cpu_get_reg (cpu
, reg
);
279 cpu_set_reg (cpu
, reg
, addr
+ sval
);
280 if ((code
& 0x10) == 0)
286 /* [n,r] 16-bits offset indexed indirect. */
287 else if ((code
& 0x07) == 3)
293 reg
= (code
>> 3) & 0x03;
294 addr
= cpu_get_reg (cpu
, reg
);
295 addr
+= cpu_fetch16 (cpu
);
296 addr
= memory_read16 (cpu
, addr
);
297 cpu_add_cycles (cpu
, 1);
299 else if ((code
& 0x4) == 0)
305 reg
= (code
>> 3) & 0x03;
306 addr
= cpu_get_reg (cpu
, reg
);
309 sval
= cpu_fetch16 (cpu
);
310 cpu_add_cycles (cpu
, 1);
314 sval
= cpu_fetch8 (cpu
);
317 cpu_add_cycles (cpu
, 1);
323 reg
= (code
>> 3) & 0x03;
324 addr
= cpu_get_reg (cpu
, reg
);
328 addr
+= cpu_get_a (cpu
);
331 addr
+= cpu_get_b (cpu
);
334 addr
+= cpu_get_d (cpu
);
338 addr
+= cpu_get_d (cpu
);
339 addr
= memory_read16 (cpu
, addr
);
340 cpu_add_cycles (cpu
, 1);
349 cpu_get_indexed_operand8 (sim_cpu
* cpu
, int restrict
)
353 addr
= cpu_get_indexed_operand_addr (cpu
, restrict
);
354 return memory_read8 (cpu
, addr
);
358 cpu_get_indexed_operand16 (sim_cpu
* cpu
, int restrict
)
362 addr
= cpu_get_indexed_operand_addr (cpu
, restrict
);
363 return memory_read16 (cpu
, addr
);
367 cpu_move8 (sim_cpu
*cpu
, uint8 code
)
375 src
= cpu_fetch8 (cpu
);
376 addr
= cpu_fetch16 (cpu
);
380 addr
= cpu_get_indexed_operand_addr (cpu
, 1);
381 src
= cpu_fetch8 (cpu
);
385 addr
= cpu_fetch16 (cpu
);
386 src
= memory_read8 (cpu
, addr
);
387 addr
= cpu_fetch16 (cpu
);
391 addr
= cpu_get_indexed_operand_addr (cpu
, 1);
392 src
= memory_read8 (cpu
, cpu_fetch16 (cpu
));
396 src
= cpu_get_indexed_operand8 (cpu
, 1);
397 addr
= cpu_fetch16 (cpu
);
401 src
= cpu_get_indexed_operand8 (cpu
, 1);
402 addr
= cpu_get_indexed_operand_addr (cpu
, 1);
406 sim_engine_abort (CPU_STATE (cpu
), cpu
, 0,
407 "Invalid code 0x%0x -- internal error?", code
);
410 memory_write8 (cpu
, addr
, src
);
414 cpu_move16 (sim_cpu
*cpu
, uint8 code
)
422 src
= cpu_fetch16 (cpu
);
423 addr
= cpu_fetch16 (cpu
);
427 addr
= cpu_get_indexed_operand_addr (cpu
, 1);
428 src
= cpu_fetch16 (cpu
);
432 addr
= cpu_fetch16 (cpu
);
433 src
= memory_read16 (cpu
, addr
);
434 addr
= cpu_fetch16 (cpu
);
438 addr
= cpu_get_indexed_operand_addr (cpu
, 1);
439 src
= memory_read16 (cpu
, cpu_fetch16 (cpu
));
443 src
= cpu_get_indexed_operand16 (cpu
, 1);
444 addr
= cpu_fetch16 (cpu
);
448 src
= cpu_get_indexed_operand16 (cpu
, 1);
449 addr
= cpu_get_indexed_operand_addr (cpu
, 1);
453 sim_engine_abort (CPU_STATE (cpu
), cpu
, 0,
454 "Invalid code 0x%0x -- internal error?", code
);
457 memory_write16 (cpu
, addr
, src
);
461 cpu_initialize (SIM_DESC sd
, sim_cpu
*cpu
)
463 sim_add_option_table (sd
, 0, cpu_options
);
465 memset (&cpu
->cpu_regs
, 0, sizeof(cpu
->cpu_regs
));
467 cpu
->cpu_absolute_cycle
= 0;
468 cpu
->cpu_current_cycle
= 0;
469 cpu
->cpu_emul_syscall
= 1;
470 cpu
->cpu_running
= 1;
471 cpu
->cpu_stop_on_interrupt
= 0;
472 cpu
->cpu_frequency
= 8 * 1000 * 1000;
473 cpu
->cpu_use_elf_start
= 0;
474 cpu
->cpu_elf_start
= 0;
475 cpu
->cpu_use_local_config
= 0;
479 cpu
->cpu_config
= M6811_NOSEC
| M6811_NOCOP
| M6811_ROMON
|
481 interrupts_initialize (sd
, cpu
);
483 cpu
->cpu_is_initialized
= 1;
488 /* Reinitialize the processor after a reset. */
490 cpu_reset (sim_cpu
*cpu
)
492 /* Initialize the config register.
493 It is only initialized at reset time. */
494 memset (cpu
->ios
, 0, sizeof (cpu
->ios
));
495 if (cpu
->cpu_configured_arch
->arch
== bfd_arch_m68hc11
)
496 cpu
->ios
[M6811_INIT
] = 0x1;
498 cpu
->ios
[M6811_INIT
] = 0;
500 /* Output compare registers set to 0xFFFF. */
501 cpu
->ios
[M6811_TOC1_H
] = 0xFF;
502 cpu
->ios
[M6811_TOC1_L
] = 0xFF;
503 cpu
->ios
[M6811_TOC2_H
] = 0xFF;
504 cpu
->ios
[M6811_TOC2_L
] = 0xFF;
505 cpu
->ios
[M6811_TOC3_H
] = 0xFF;
506 cpu
->ios
[M6811_TOC4_L
] = 0xFF;
507 cpu
->ios
[M6811_TOC5_H
] = 0xFF;
508 cpu
->ios
[M6811_TOC5_L
] = 0xFF;
510 /* Setup the processor registers. */
511 memset (&cpu
->cpu_regs
, 0, sizeof(cpu
->cpu_regs
));
512 cpu
->cpu_absolute_cycle
= 0;
513 cpu
->cpu_current_cycle
= 0;
514 cpu
->cpu_is_initialized
= 0;
516 /* Reset interrupts. */
517 interrupts_reset (&cpu
->cpu_interrupts
);
519 /* Reinitialize the CPU operating mode. */
520 cpu
->ios
[M6811_HPRIO
] = cpu
->cpu_mode
;
524 /* Reinitialize the processor after a reset. */
526 cpu_restart (sim_cpu
*cpu
)
530 /* Get CPU starting address depending on the CPU mode. */
531 if (cpu
->cpu_use_elf_start
== 0)
533 switch ((cpu
->ios
[M6811_HPRIO
]) & (M6811_SMOD
| M6811_MDA
))
538 addr
= memory_read16 (cpu
, 0xFFFE);
541 /* Expanded Multiplexed */
543 addr
= memory_read16 (cpu
, 0xFFFE);
546 /* Special Bootstrap */
552 case M6811_MDA
| M6811_SMOD
:
553 addr
= memory_read16 (cpu
, 0xFFFE);
559 addr
= cpu
->cpu_elf_start
;
562 /* Setup the processor registers. */
563 cpu
->cpu_insn_pc
= addr
;
564 cpu
->cpu_regs
.pc
= addr
;
565 cpu
->cpu_regs
.ccr
= M6811_X_BIT
| M6811_I_BIT
| M6811_S_BIT
;
566 cpu
->cpu_absolute_cycle
= 0;
567 cpu
->cpu_is_initialized
= 1;
568 cpu
->cpu_current_cycle
= 0;
570 cpu_call (cpu
, addr
);
576 print_io_reg_desc (SIM_DESC sd
, io_reg_desc
*desc
, int val
, int mode
)
580 if (val
& desc
->mask
)
581 sim_io_printf (sd
, "%s",
582 mode
== 0 ? desc
->short_name
: desc
->long_name
);
588 print_io_byte (SIM_DESC sd
, const char *name
, io_reg_desc
*desc
,
589 uint8 val
, uint16 addr
)
591 sim_io_printf (sd
, " %-9.9s @ 0x%04x 0x%02x ", name
, addr
, val
);
593 print_io_reg_desc (sd
, desc
, val
, 0);
597 print_io_word (SIM_DESC sd
, const char *name
, io_reg_desc
*desc
,
598 uint16 val
, uint16 addr
)
600 sim_io_printf (sd
, " %-9.9s @ 0x%04x 0x%04x ", name
, addr
, val
);
602 print_io_reg_desc (sd
, desc
, val
, 0);
606 cpu_ccr_update_tst8 (sim_cpu
*proc
, uint8 val
)
608 cpu_set_ccr_V (proc
, 0);
609 cpu_set_ccr_N (proc
, val
& 0x80 ? 1 : 0);
610 cpu_set_ccr_Z (proc
, val
== 0 ? 1 : 0);
615 cpu_fetch_relbranch (sim_cpu
*cpu
)
617 uint16 addr
= (uint16
) cpu_fetch8 (cpu
);
623 addr
+= cpu
->cpu_regs
.pc
;
628 cpu_fetch_relbranch16 (sim_cpu
*cpu
)
630 uint16 addr
= cpu_fetch16 (cpu
);
632 addr
+= cpu
->cpu_regs
.pc
;
636 /* Push all the CPU registers (when an interruption occurs). */
638 cpu_push_all (sim_cpu
*cpu
)
640 if (cpu
->cpu_configured_arch
->arch
== bfd_arch_m68hc11
)
642 cpu_m68hc11_push_uint16 (cpu
, cpu
->cpu_regs
.pc
);
643 cpu_m68hc11_push_uint16 (cpu
, cpu
->cpu_regs
.iy
);
644 cpu_m68hc11_push_uint16 (cpu
, cpu
->cpu_regs
.ix
);
645 cpu_m68hc11_push_uint16 (cpu
, cpu
->cpu_regs
.d
);
646 cpu_m68hc11_push_uint8 (cpu
, cpu
->cpu_regs
.ccr
);
650 cpu_m68hc12_push_uint16 (cpu
, cpu
->cpu_regs
.pc
);
651 cpu_m68hc12_push_uint16 (cpu
, cpu
->cpu_regs
.iy
);
652 cpu_m68hc12_push_uint16 (cpu
, cpu
->cpu_regs
.ix
);
653 cpu_m68hc12_push_uint16 (cpu
, cpu
->cpu_regs
.d
);
654 cpu_m68hc12_push_uint8 (cpu
, cpu
->cpu_regs
.ccr
);
658 /* Simulation of the dbcc/ibcc/tbcc 68HC12 conditional branch operations. */
660 cpu_dbcc (sim_cpu
* cpu
)
667 code
= cpu_fetch8 (cpu
);
670 case 0x80: /* ibcc */
673 case 0x40: /* tbcc */
684 addr
= cpu_fetch8 (cpu
);
688 addr
+= cpu_get_pc (cpu
);
689 reg
= cpu_get_src_reg (cpu
, code
& 0x07);
692 /* Branch according to register value. */
693 if ((reg
!= 0 && (code
& 0x20)) || (reg
== 0 && !(code
& 0x20)))
695 cpu_set_pc (cpu
, addr
);
697 cpu_set_dst_reg (cpu
, code
& 0x07, reg
);
701 cpu_exg (sim_cpu
* cpu
, uint8 code
)
707 r1
= (code
>> 4) & 0x07;
711 src1
= cpu_get_src_reg (cpu
, r1
);
712 src2
= cpu_get_src_reg (cpu
, r2
);
713 if (r2
== 1 || r2
== 2)
716 cpu_set_dst_reg (cpu
, r2
, src1
);
717 cpu_set_dst_reg (cpu
, r1
, src2
);
721 src1
= cpu_get_src_reg (cpu
, r1
);
723 /* Sign extend the 8-bit registers (A, B, CCR). */
724 if ((r1
== 0 || r1
== 1 || r1
== 2) && (src1
& 0x80))
727 cpu_set_dst_reg (cpu
, r2
, src1
);
731 /* Handle special instructions. */
733 cpu_special (sim_cpu
*cpu
, enum M6811_Special special
)
741 ccr
= cpu_m68hc11_pop_uint8 (cpu
);
742 cpu_set_ccr (cpu
, ccr
);
743 cpu_set_d (cpu
, cpu_m68hc11_pop_uint16 (cpu
));
744 cpu_set_x (cpu
, cpu_m68hc11_pop_uint16 (cpu
));
745 cpu_set_y (cpu
, cpu_m68hc11_pop_uint16 (cpu
));
746 cpu_set_pc (cpu
, cpu_m68hc11_pop_uint16 (cpu
));
755 ccr
= cpu_m68hc12_pop_uint8 (cpu
);
756 cpu_set_ccr (cpu
, ccr
);
757 cpu_set_d (cpu
, cpu_m68hc12_pop_uint16 (cpu
));
758 cpu_set_x (cpu
, cpu_m68hc12_pop_uint16 (cpu
));
759 cpu_set_y (cpu
, cpu_m68hc12_pop_uint16 (cpu
));
760 cpu_set_pc (cpu
, cpu_m68hc12_pop_uint16 (cpu
));
766 /* In the ELF-start mode, we are in a special mode where
767 the WAI corresponds to an exit. */
768 if (cpu
->cpu_use_elf_start
)
770 cpu_set_pc (cpu
, cpu
->cpu_insn_pc
);
771 sim_engine_halt (CPU_STATE (cpu
), cpu
,
772 NULL
, NULL_CIA
, sim_exited
,
776 /* SCz: not correct... */
781 interrupts_raise (&cpu
->cpu_interrupts
, M6811_INT_SWI
);
782 interrupts_process (&cpu
->cpu_interrupts
);
785 case M6811_EMUL_SYSCALL
:
787 if (cpu
->cpu_emul_syscall
)
789 uint8 op
= memory_read8 (cpu
,
790 cpu_get_pc (cpu
) - 1);
793 cpu_set_pc (cpu
, cpu
->cpu_insn_pc
);
794 sim_engine_halt (CPU_STATE (cpu
), cpu
,
795 NULL
, NULL_CIA
, sim_exited
,
806 interrupts_raise (&cpu
->cpu_interrupts
, M6811_INT_ILLEGAL
);
807 interrupts_process (&cpu
->cpu_interrupts
);
815 sd
= CPU_STATE (cpu
);
817 /* Breakpoint instruction if we are under gdb. */
818 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
821 sim_engine_halt (CPU_STATE (cpu
), cpu
,
822 0, cpu_get_pc (cpu
), sim_stopped
,
825 /* else this is a nop but not in test factory mode. */
831 int32 src1
= (int16
) cpu_get_d (cpu
);
832 int32 src2
= (int16
) cpu_get_x (cpu
);
836 cpu_set_ccr_C (cpu
, 1);
840 cpu_set_d (cpu
, src1
% src2
);
842 cpu_set_x (cpu
, src1
);
843 cpu_set_ccr_C (cpu
, 0);
844 cpu_set_ccr_Z (cpu
, src1
== 0);
845 cpu_set_ccr_N (cpu
, src1
& 0x8000);
846 cpu_set_ccr_V (cpu
, src1
>= 32768 || src1
< -32768);
853 uint32 src1
= (uint32
) cpu_get_x (cpu
);
854 uint32 src2
= (uint32
) (cpu_get_y (cpu
) << 16)
855 | (uint32
) (cpu_get_d (cpu
));
859 cpu_set_ccr_C (cpu
, 1);
863 cpu_set_ccr_C (cpu
, 0);
864 cpu_set_d (cpu
, src2
% src1
);
866 cpu_set_y (cpu
, src2
);
867 cpu_set_ccr_Z (cpu
, src2
== 0);
868 cpu_set_ccr_N (cpu
, (src2
& 0x8000) != 0);
869 cpu_set_ccr_V (cpu
, (src2
& 0xffff0000) != 0);
876 int32 src1
= (int16
) cpu_get_x (cpu
);
877 int32 src2
= (uint32
) (cpu_get_y (cpu
) << 16)
878 | (uint32
) (cpu_get_d (cpu
));
882 cpu_set_ccr_C (cpu
, 1);
886 cpu_set_ccr_C (cpu
, 0);
887 cpu_set_d (cpu
, src2
% src1
);
889 cpu_set_y (cpu
, src2
);
890 cpu_set_ccr_Z (cpu
, src2
== 0);
891 cpu_set_ccr_N (cpu
, (src2
& 0x8000) != 0);
892 cpu_set_ccr_V (cpu
, src2
> 32767 || src2
< -32768);
901 src1
= (int16
) cpu_get_d (cpu
);
902 src2
= (int16
) cpu_get_y (cpu
);
904 cpu_set_d (cpu
, src1
& 0x0ffff);
905 cpu_set_y (cpu
, src1
>> 16);
906 cpu_set_ccr_Z (cpu
, src1
== 0);
907 cpu_set_ccr_N (cpu
, (src1
& 0x80000000) != 0);
908 cpu_set_ccr_C (cpu
, (src1
& 0x00008000) != 0);
917 addr
= cpu_fetch16 (cpu
);
918 src1
= (int16
) memory_read16 (cpu
, cpu_get_x (cpu
));
919 src2
= (int16
) memory_read16 (cpu
, cpu_get_y (cpu
));
921 src2
= (((uint32
) memory_read16 (cpu
, addr
)) << 16)
922 | (uint32
) memory_read16 (cpu
, addr
+ 2);
924 memory_write16 (cpu
, addr
, (src1
+ src2
) >> 16);
925 memory_write16 (cpu
, addr
+ 2, (src1
+ src2
));
936 addr
= cpu_fetch16 (cpu
);
937 page
= cpu_fetch8 (cpu
);
939 cpu_m68hc12_push_uint16 (cpu
, cpu_get_pc (cpu
));
940 cpu_m68hc12_push_uint8 (cpu
, cpu_get_page (cpu
));
942 cpu_set_page (cpu
, page
);
943 cpu_set_pc (cpu
, addr
);
947 case M6812_CALL_INDIRECT
:
953 code
= memory_read8 (cpu
, cpu_get_pc (cpu
));
954 /* Indirect addressing call has the page specified in the
955 memory location pointed to by the address. */
956 if ((code
& 0xE3) == 0xE3)
958 addr
= cpu_get_indexed_operand_addr (cpu
, 0);
959 page
= memory_read8 (cpu
, addr
+ 2);
960 addr
= memory_read16 (cpu
, addr
);
964 /* Otherwise, page is in the opcode. */
965 addr
= cpu_get_indexed_operand16 (cpu
, 0);
966 page
= cpu_fetch8 (cpu
);
968 cpu_m68hc12_push_uint16 (cpu
, cpu_get_pc (cpu
));
969 cpu_m68hc12_push_uint8 (cpu
, cpu_get_page (cpu
));
970 cpu_set_page (cpu
, page
);
971 cpu_set_pc (cpu
, addr
);
977 uint8 page
= cpu_m68hc12_pop_uint8 (cpu
);
978 uint16 addr
= cpu_m68hc12_pop_uint16 (cpu
);
980 cpu_set_page (cpu
, page
);
981 cpu_set_pc (cpu
, addr
);
987 sim_engine_halt (CPU_STATE (cpu
), cpu
, NULL
,
988 cpu_get_pc (cpu
), sim_stopped
,
996 cpu_single_step (sim_cpu
*cpu
)
998 cpu
->cpu_current_cycle
= 0;
999 cpu
->cpu_insn_pc
= cpu_get_pc (cpu
);
1001 /* Handle the pending interrupts. If an interrupt is handled,
1002 treat this as an single step. */
1003 if (interrupts_process (&cpu
->cpu_interrupts
))
1005 cpu
->cpu_absolute_cycle
+= cpu
->cpu_current_cycle
;
1009 /* printf("PC = 0x%04x\n", cpu_get_pc (cpu));*/
1010 cpu
->cpu_interpretor (cpu
);
1011 cpu
->cpu_absolute_cycle
+= cpu
->cpu_current_cycle
;
1016 sim_memory_error (sim_cpu
*cpu
, SIM_SIGNAL excep
,
1017 uint16 addr
, const char *message
, ...)
1022 va_start (args
, message
);
1023 vsprintf (buf
, message
, args
);
1026 sim_io_printf (CPU_STATE (cpu
), "%s\n", buf
);
1027 cpu_memory_exception (cpu
, excep
, addr
, buf
);
1032 cpu_memory_exception (sim_cpu
*cpu
, SIM_SIGNAL excep
,
1033 uint16 addr
, const char *message
)
1035 if (cpu
->cpu_running
== 0)
1038 cpu_set_pc (cpu
, cpu
->cpu_insn_pc
);
1039 sim_engine_halt (CPU_STATE (cpu
), cpu
, NULL
,
1040 cpu_get_pc (cpu
), sim_stopped
, excep
);
1043 cpu
->mem_exception
= excep
;
1044 cpu
->fault_addr
= addr
;
1045 cpu
->fault_msg
= strdup (message
);
1047 if (cpu
->cpu_use_handler
)
1049 longjmp (&cpu
->cpu_exception_handler
, 1);
1051 (* cpu
->callback
->printf_filtered
)
1052 (cpu
->callback
, "Fault at 0x%04x: %s\n", addr
, message
);
1057 cpu_info (SIM_DESC sd
, sim_cpu
*cpu
)
1059 sim_io_printf (sd
, "CPU info:\n");
1060 sim_io_printf (sd
, " Absolute cycle: %s\n",
1061 cycle_to_string (cpu
, cpu
->cpu_absolute_cycle
,
1062 PRINT_TIME
| PRINT_CYCLE
));
1064 sim_io_printf (sd
, " Syscall emulation: %s\n",
1065 cpu
->cpu_emul_syscall
? "yes, via 0xcd <n>" : "no");
1066 sim_io_printf (sd
, " Memory errors detection: %s\n",
1067 cpu
->cpu_check_memory
? "yes" : "no");
1068 sim_io_printf (sd
, " Stop on interrupt: %s\n",
1069 cpu
->cpu_stop_on_interrupt
? "yes" : "no");