]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/m68hc11/m68hc11_sim.c
93a4e0b9dc501f02fa414ee1fe528ecedfe17a3a
1 /* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation
2 Copyright 1999, 2000, 2001, 2002, 2003, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Written by Stephane Carrez (stcarrez@nerim.fr)
6 This file is part of GDB, GAS, and the GNU binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
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");