m68hc11_sim.c revision 1.1.1.8 1 1.1 christos /* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation
2 1.1.1.8 christos Copyright 1999-2023 Free Software Foundation, Inc.
3 1.1 christos Written by Stephane Carrez (stcarrez (at) nerim.fr)
4 1.1 christos
5 1.1 christos This file is part of GDB, GAS, and the GNU binutils.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1.1.8 christos /* This must come before any other includes. */
21 1.1.1.8 christos #include "defs.h"
22 1.1.1.8 christos
23 1.1 christos #include "sim-main.h"
24 1.1 christos #include "sim-assert.h"
25 1.1 christos #include "sim-module.h"
26 1.1 christos #include "sim-options.h"
27 1.1.1.8 christos #include "sim-signal.h"
28 1.1.1.8 christos
29 1.1.1.8 christos #include <stdlib.h>
30 1.1 christos
31 1.1 christos enum {
32 1.1 christos OPTION_CPU_RESET = OPTION_START,
33 1.1 christos OPTION_EMUL_OS,
34 1.1 christos OPTION_CPU_CONFIG,
35 1.1 christos OPTION_CPU_BOOTSTRAP,
36 1.1 christos OPTION_CPU_MODE
37 1.1 christos };
38 1.1 christos
39 1.1 christos static DECLARE_OPTION_HANDLER (cpu_option_handler);
40 1.1 christos
41 1.1 christos static const OPTION cpu_options[] =
42 1.1 christos {
43 1.1 christos { {"cpu-reset", no_argument, NULL, OPTION_CPU_RESET },
44 1.1 christos '\0', NULL, "Reset the CPU",
45 1.1 christos cpu_option_handler },
46 1.1 christos
47 1.1 christos { {"emulos", no_argument, NULL, OPTION_EMUL_OS },
48 1.1 christos '\0', NULL, "Emulate some OS system calls (read, write, ...)",
49 1.1 christos cpu_option_handler },
50 1.1 christos
51 1.1 christos { {"cpu-config", required_argument, NULL, OPTION_CPU_CONFIG },
52 1.1 christos '\0', NULL, "Specify the initial CPU configuration register",
53 1.1 christos cpu_option_handler },
54 1.1 christos
55 1.1 christos { {"bootstrap", no_argument, NULL, OPTION_CPU_BOOTSTRAP },
56 1.1 christos '\0', NULL, "Start the processing in bootstrap mode",
57 1.1 christos cpu_option_handler },
58 1.1 christos
59 1.1 christos { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
60 1.1 christos };
61 1.1 christos
62 1.1 christos
63 1.1 christos static SIM_RC
64 1.1 christos cpu_option_handler (SIM_DESC sd, sim_cpu *cpu,
65 1.1 christos int opt, char *arg, int is_command)
66 1.1 christos {
67 1.1 christos int val;
68 1.1 christos
69 1.1 christos cpu = STATE_CPU (sd, 0);
70 1.1 christos switch (opt)
71 1.1 christos {
72 1.1 christos case OPTION_CPU_RESET:
73 1.1 christos sim_board_reset (sd);
74 1.1 christos break;
75 1.1 christos
76 1.1 christos case OPTION_EMUL_OS:
77 1.1 christos cpu->cpu_emul_syscall = 1;
78 1.1 christos break;
79 1.1 christos
80 1.1 christos case OPTION_CPU_CONFIG:
81 1.1 christos if (sscanf(arg, "0x%x", &val) == 1
82 1.1 christos || sscanf(arg, "%d", &val) == 1)
83 1.1 christos {
84 1.1 christos cpu->cpu_config = val;
85 1.1 christos cpu->cpu_use_local_config = 1;
86 1.1 christos }
87 1.1 christos else
88 1.1 christos cpu->cpu_use_local_config = 0;
89 1.1 christos break;
90 1.1 christos
91 1.1 christos case OPTION_CPU_BOOTSTRAP:
92 1.1 christos cpu->cpu_start_mode = "bootstrap";
93 1.1 christos break;
94 1.1 christos
95 1.1 christos case OPTION_CPU_MODE:
96 1.1 christos break;
97 1.1 christos }
98 1.1 christos
99 1.1 christos return SIM_RC_OK;
100 1.1 christos }
101 1.1 christos
102 1.1 christos
103 1.1 christos void
104 1.1.1.8 christos cpu_call (sim_cpu *cpu, uint16_t addr)
105 1.1 christos {
106 1.1 christos
107 1.1 christos cpu_set_pc (cpu, addr);
108 1.1 christos }
109 1.1 christos
110 1.1 christos void
111 1.1 christos cpu_return (sim_cpu *cpu)
112 1.1 christos {
113 1.1 christos }
114 1.1 christos
115 1.1 christos /* Set the stack pointer and re-compute the current frame. */
116 1.1 christos void
117 1.1.1.8 christos cpu_set_sp (sim_cpu *cpu, uint16_t val)
118 1.1 christos {
119 1.1 christos cpu->cpu_regs.sp = val;
120 1.1 christos }
121 1.1 christos
122 1.1.1.8 christos static uint16_t
123 1.1.1.8 christos cpu_get_reg (sim_cpu *cpu, uint8_t reg)
124 1.1 christos {
125 1.1 christos switch (reg)
126 1.1 christos {
127 1.1 christos case 0:
128 1.1 christos return cpu_get_x (cpu);
129 1.1 christos
130 1.1 christos case 1:
131 1.1 christos return cpu_get_y (cpu);
132 1.1 christos
133 1.1 christos case 2:
134 1.1 christos return cpu_get_sp (cpu);
135 1.1 christos
136 1.1 christos case 3:
137 1.1 christos return cpu_get_pc (cpu);
138 1.1 christos
139 1.1 christos default:
140 1.1 christos return 0;
141 1.1 christos }
142 1.1 christos }
143 1.1 christos
144 1.1.1.8 christos static uint16_t
145 1.1.1.8 christos cpu_get_src_reg (sim_cpu *cpu, uint8_t reg)
146 1.1 christos {
147 1.1 christos switch (reg)
148 1.1 christos {
149 1.1 christos case 0:
150 1.1 christos return cpu_get_a (cpu);
151 1.1 christos
152 1.1 christos case 1:
153 1.1 christos return cpu_get_b (cpu);
154 1.1 christos
155 1.1 christos case 2:
156 1.1 christos return cpu_get_ccr (cpu);
157 1.1 christos
158 1.1 christos case 3:
159 1.1 christos return cpu_get_tmp3 (cpu);
160 1.1 christos
161 1.1 christos case 4:
162 1.1 christos return cpu_get_d (cpu);
163 1.1 christos
164 1.1 christos case 5:
165 1.1 christos return cpu_get_x (cpu);
166 1.1 christos
167 1.1 christos case 6:
168 1.1 christos return cpu_get_y (cpu);
169 1.1 christos
170 1.1 christos case 7:
171 1.1 christos return cpu_get_sp (cpu);
172 1.1 christos
173 1.1 christos default:
174 1.1 christos return 0;
175 1.1 christos }
176 1.1 christos }
177 1.1 christos
178 1.1.1.8 christos static void
179 1.1.1.8 christos cpu_set_dst_reg (sim_cpu *cpu, uint8_t reg, uint16_t val)
180 1.1 christos {
181 1.1 christos switch (reg)
182 1.1 christos {
183 1.1 christos case 0:
184 1.1 christos cpu_set_a (cpu, val);
185 1.1 christos break;
186 1.1 christos
187 1.1 christos case 1:
188 1.1 christos cpu_set_b (cpu, val);
189 1.1 christos break;
190 1.1 christos
191 1.1 christos case 2:
192 1.1 christos cpu_set_ccr (cpu, val);
193 1.1 christos break;
194 1.1 christos
195 1.1 christos case 3:
196 1.1 christos cpu_set_tmp2 (cpu, val);
197 1.1 christos break;
198 1.1 christos
199 1.1 christos case 4:
200 1.1 christos cpu_set_d (cpu, val);
201 1.1 christos break;
202 1.1 christos
203 1.1 christos case 5:
204 1.1 christos cpu_set_x (cpu, val);
205 1.1 christos break;
206 1.1 christos
207 1.1 christos case 6:
208 1.1 christos cpu_set_y (cpu, val);
209 1.1 christos break;
210 1.1 christos
211 1.1 christos case 7:
212 1.1 christos cpu_set_sp (cpu, val);
213 1.1 christos break;
214 1.1 christos
215 1.1 christos default:
216 1.1 christos break;
217 1.1 christos }
218 1.1 christos }
219 1.1 christos
220 1.1.1.8 christos static void
221 1.1.1.8 christos cpu_set_reg (sim_cpu *cpu, uint8_t reg, uint16_t val)
222 1.1 christos {
223 1.1 christos switch (reg)
224 1.1 christos {
225 1.1 christos case 0:
226 1.1 christos cpu_set_x (cpu, val);
227 1.1 christos break;
228 1.1 christos
229 1.1 christos case 1:
230 1.1 christos cpu_set_y (cpu, val);
231 1.1 christos break;
232 1.1 christos
233 1.1 christos case 2:
234 1.1 christos cpu_set_sp (cpu, val);
235 1.1 christos break;
236 1.1 christos
237 1.1 christos case 3:
238 1.1 christos cpu_set_pc (cpu, val);
239 1.1 christos break;
240 1.1 christos
241 1.1 christos default:
242 1.1 christos break;
243 1.1 christos }
244 1.1 christos }
245 1.1 christos
246 1.1 christos /* Returns the address of a 68HC12 indexed operand.
247 1.1 christos Pre and post modifications are handled on the source register. */
248 1.1.1.8 christos uint16_t
249 1.1.1.5 christos cpu_get_indexed_operand_addr (sim_cpu *cpu, int restricted)
250 1.1 christos {
251 1.1.1.8 christos uint8_t reg;
252 1.1.1.8 christos uint16_t sval;
253 1.1.1.8 christos uint16_t addr;
254 1.1.1.8 christos uint8_t code;
255 1.1 christos
256 1.1 christos code = cpu_fetch8 (cpu);
257 1.1 christos
258 1.1 christos /* n,r with 5-bit signed constant. */
259 1.1 christos if ((code & 0x20) == 0)
260 1.1 christos {
261 1.1 christos reg = (code >> 6) & 3;
262 1.1 christos sval = (code & 0x1f);
263 1.1 christos if (code & 0x10)
264 1.1 christos sval |= 0xfff0;
265 1.1 christos
266 1.1 christos addr = cpu_get_reg (cpu, reg);
267 1.1 christos addr += sval;
268 1.1 christos }
269 1.1 christos
270 1.1 christos /* Auto pre/post increment/decrement. */
271 1.1 christos else if ((code & 0xc0) != 0xc0)
272 1.1 christos {
273 1.1 christos reg = (code >> 6) & 3;
274 1.1 christos sval = (code & 0x0f);
275 1.1 christos if (sval & 0x8)
276 1.1 christos {
277 1.1 christos sval |= 0xfff0;
278 1.1 christos }
279 1.1 christos else
280 1.1 christos {
281 1.1 christos sval = sval + 1;
282 1.1 christos }
283 1.1 christos addr = cpu_get_reg (cpu, reg);
284 1.1 christos cpu_set_reg (cpu, reg, addr + sval);
285 1.1 christos if ((code & 0x10) == 0)
286 1.1 christos {
287 1.1 christos addr += sval;
288 1.1 christos }
289 1.1 christos }
290 1.1 christos
291 1.1 christos /* [n,r] 16-bits offset indexed indirect. */
292 1.1 christos else if ((code & 0x07) == 3)
293 1.1 christos {
294 1.1.1.3 christos if (restricted)
295 1.1 christos {
296 1.1 christos return 0;
297 1.1 christos }
298 1.1 christos reg = (code >> 3) & 0x03;
299 1.1 christos addr = cpu_get_reg (cpu, reg);
300 1.1 christos addr += cpu_fetch16 (cpu);
301 1.1 christos addr = memory_read16 (cpu, addr);
302 1.1 christos cpu_add_cycles (cpu, 1);
303 1.1 christos }
304 1.1 christos else if ((code & 0x4) == 0)
305 1.1 christos {
306 1.1.1.3 christos if (restricted)
307 1.1 christos {
308 1.1 christos return 0;
309 1.1 christos }
310 1.1 christos reg = (code >> 3) & 0x03;
311 1.1 christos addr = cpu_get_reg (cpu, reg);
312 1.1 christos if (code & 0x2)
313 1.1 christos {
314 1.1 christos sval = cpu_fetch16 (cpu);
315 1.1 christos cpu_add_cycles (cpu, 1);
316 1.1 christos }
317 1.1 christos else
318 1.1 christos {
319 1.1 christos sval = cpu_fetch8 (cpu);
320 1.1 christos if (code & 0x1)
321 1.1 christos sval |= 0xff00;
322 1.1 christos cpu_add_cycles (cpu, 1);
323 1.1 christos }
324 1.1 christos addr += sval;
325 1.1 christos }
326 1.1 christos else
327 1.1 christos {
328 1.1 christos reg = (code >> 3) & 0x03;
329 1.1 christos addr = cpu_get_reg (cpu, reg);
330 1.1 christos switch (code & 3)
331 1.1 christos {
332 1.1 christos case 0:
333 1.1 christos addr += cpu_get_a (cpu);
334 1.1 christos break;
335 1.1 christos case 1:
336 1.1 christos addr += cpu_get_b (cpu);
337 1.1 christos break;
338 1.1 christos case 2:
339 1.1 christos addr += cpu_get_d (cpu);
340 1.1 christos break;
341 1.1 christos case 3:
342 1.1 christos default:
343 1.1 christos addr += cpu_get_d (cpu);
344 1.1 christos addr = memory_read16 (cpu, addr);
345 1.1 christos cpu_add_cycles (cpu, 1);
346 1.1 christos break;
347 1.1 christos }
348 1.1 christos }
349 1.1 christos
350 1.1 christos return addr;
351 1.1 christos }
352 1.1 christos
353 1.1.1.8 christos static uint8_t
354 1.1.1.5 christos cpu_get_indexed_operand8 (sim_cpu *cpu, int restricted)
355 1.1 christos {
356 1.1.1.8 christos uint16_t addr;
357 1.1 christos
358 1.1.1.3 christos addr = cpu_get_indexed_operand_addr (cpu, restricted);
359 1.1 christos return memory_read8 (cpu, addr);
360 1.1 christos }
361 1.1 christos
362 1.1.1.8 christos static uint16_t
363 1.1.1.5 christos cpu_get_indexed_operand16 (sim_cpu *cpu, int restricted)
364 1.1 christos {
365 1.1.1.8 christos uint16_t addr;
366 1.1 christos
367 1.1.1.3 christos addr = cpu_get_indexed_operand_addr (cpu, restricted);
368 1.1 christos return memory_read16 (cpu, addr);
369 1.1 christos }
370 1.1 christos
371 1.1 christos void
372 1.1.1.8 christos cpu_move8 (sim_cpu *cpu, uint8_t code)
373 1.1 christos {
374 1.1.1.8 christos uint8_t src;
375 1.1.1.8 christos uint16_t addr;
376 1.1 christos
377 1.1 christos switch (code)
378 1.1 christos {
379 1.1 christos case 0x0b:
380 1.1 christos src = cpu_fetch8 (cpu);
381 1.1 christos addr = cpu_fetch16 (cpu);
382 1.1 christos break;
383 1.1 christos
384 1.1 christos case 0x08:
385 1.1 christos addr = cpu_get_indexed_operand_addr (cpu, 1);
386 1.1 christos src = cpu_fetch8 (cpu);
387 1.1 christos break;
388 1.1 christos
389 1.1 christos case 0x0c:
390 1.1 christos addr = cpu_fetch16 (cpu);
391 1.1 christos src = memory_read8 (cpu, addr);
392 1.1 christos addr = cpu_fetch16 (cpu);
393 1.1 christos break;
394 1.1 christos
395 1.1 christos case 0x09:
396 1.1 christos addr = cpu_get_indexed_operand_addr (cpu, 1);
397 1.1 christos src = memory_read8 (cpu, cpu_fetch16 (cpu));
398 1.1 christos break;
399 1.1 christos
400 1.1 christos case 0x0d:
401 1.1 christos src = cpu_get_indexed_operand8 (cpu, 1);
402 1.1 christos addr = cpu_fetch16 (cpu);
403 1.1 christos break;
404 1.1 christos
405 1.1 christos case 0x0a:
406 1.1 christos src = cpu_get_indexed_operand8 (cpu, 1);
407 1.1 christos addr = cpu_get_indexed_operand_addr (cpu, 1);
408 1.1 christos break;
409 1.1 christos
410 1.1 christos default:
411 1.1 christos sim_engine_abort (CPU_STATE (cpu), cpu, 0,
412 1.1 christos "Invalid code 0x%0x -- internal error?", code);
413 1.1 christos return;
414 1.1 christos }
415 1.1 christos memory_write8 (cpu, addr, src);
416 1.1 christos }
417 1.1 christos
418 1.1 christos void
419 1.1.1.8 christos cpu_move16 (sim_cpu *cpu, uint8_t code)
420 1.1 christos {
421 1.1.1.8 christos uint16_t src;
422 1.1.1.8 christos uint16_t addr;
423 1.1 christos
424 1.1 christos switch (code)
425 1.1 christos {
426 1.1 christos case 0x03:
427 1.1 christos src = cpu_fetch16 (cpu);
428 1.1 christos addr = cpu_fetch16 (cpu);
429 1.1 christos break;
430 1.1 christos
431 1.1 christos case 0x00:
432 1.1 christos addr = cpu_get_indexed_operand_addr (cpu, 1);
433 1.1 christos src = cpu_fetch16 (cpu);
434 1.1 christos break;
435 1.1 christos
436 1.1 christos case 0x04:
437 1.1 christos addr = cpu_fetch16 (cpu);
438 1.1 christos src = memory_read16 (cpu, addr);
439 1.1 christos addr = cpu_fetch16 (cpu);
440 1.1 christos break;
441 1.1 christos
442 1.1 christos case 0x01:
443 1.1 christos addr = cpu_get_indexed_operand_addr (cpu, 1);
444 1.1 christos src = memory_read16 (cpu, cpu_fetch16 (cpu));
445 1.1 christos break;
446 1.1 christos
447 1.1 christos case 0x05:
448 1.1 christos src = cpu_get_indexed_operand16 (cpu, 1);
449 1.1 christos addr = cpu_fetch16 (cpu);
450 1.1 christos break;
451 1.1 christos
452 1.1 christos case 0x02:
453 1.1 christos src = cpu_get_indexed_operand16 (cpu, 1);
454 1.1 christos addr = cpu_get_indexed_operand_addr (cpu, 1);
455 1.1 christos break;
456 1.1 christos
457 1.1 christos default:
458 1.1 christos sim_engine_abort (CPU_STATE (cpu), cpu, 0,
459 1.1 christos "Invalid code 0x%0x -- internal error?", code);
460 1.1 christos return;
461 1.1 christos }
462 1.1 christos memory_write16 (cpu, addr, src);
463 1.1 christos }
464 1.1 christos
465 1.1 christos int
466 1.1 christos cpu_initialize (SIM_DESC sd, sim_cpu *cpu)
467 1.1 christos {
468 1.1 christos sim_add_option_table (sd, 0, cpu_options);
469 1.1 christos
470 1.1 christos memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));
471 1.1 christos
472 1.1 christos cpu->cpu_absolute_cycle = 0;
473 1.1 christos cpu->cpu_current_cycle = 0;
474 1.1 christos cpu->cpu_emul_syscall = 1;
475 1.1 christos cpu->cpu_running = 1;
476 1.1 christos cpu->cpu_stop_on_interrupt = 0;
477 1.1 christos cpu->cpu_frequency = 8 * 1000 * 1000;
478 1.1 christos cpu->cpu_use_elf_start = 0;
479 1.1 christos cpu->cpu_elf_start = 0;
480 1.1 christos cpu->cpu_use_local_config = 0;
481 1.1 christos cpu->bank_start = 0;
482 1.1 christos cpu->bank_end = 0;
483 1.1 christos cpu->bank_shift = 0;
484 1.1 christos cpu->cpu_config = M6811_NOSEC | M6811_NOCOP | M6811_ROMON |
485 1.1 christos M6811_EEON;
486 1.1 christos interrupts_initialize (sd, cpu);
487 1.1 christos
488 1.1 christos cpu->cpu_is_initialized = 1;
489 1.1 christos return 0;
490 1.1 christos }
491 1.1 christos
492 1.1 christos
493 1.1 christos /* Reinitialize the processor after a reset. */
494 1.1 christos int
495 1.1 christos cpu_reset (sim_cpu *cpu)
496 1.1 christos {
497 1.1 christos /* Initialize the config register.
498 1.1 christos It is only initialized at reset time. */
499 1.1 christos memset (cpu->ios, 0, sizeof (cpu->ios));
500 1.1 christos if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
501 1.1 christos cpu->ios[M6811_INIT] = 0x1;
502 1.1 christos else
503 1.1 christos cpu->ios[M6811_INIT] = 0;
504 1.1 christos
505 1.1 christos /* Output compare registers set to 0xFFFF. */
506 1.1 christos cpu->ios[M6811_TOC1_H] = 0xFF;
507 1.1 christos cpu->ios[M6811_TOC1_L] = 0xFF;
508 1.1 christos cpu->ios[M6811_TOC2_H] = 0xFF;
509 1.1 christos cpu->ios[M6811_TOC2_L] = 0xFF;
510 1.1 christos cpu->ios[M6811_TOC3_H] = 0xFF;
511 1.1 christos cpu->ios[M6811_TOC4_L] = 0xFF;
512 1.1 christos cpu->ios[M6811_TOC5_H] = 0xFF;
513 1.1 christos cpu->ios[M6811_TOC5_L] = 0xFF;
514 1.1 christos
515 1.1 christos /* Setup the processor registers. */
516 1.1 christos memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));
517 1.1 christos cpu->cpu_absolute_cycle = 0;
518 1.1 christos cpu->cpu_current_cycle = 0;
519 1.1 christos cpu->cpu_is_initialized = 0;
520 1.1 christos
521 1.1 christos /* Reset interrupts. */
522 1.1 christos interrupts_reset (&cpu->cpu_interrupts);
523 1.1 christos
524 1.1 christos /* Reinitialize the CPU operating mode. */
525 1.1 christos cpu->ios[M6811_HPRIO] = cpu->cpu_mode;
526 1.1 christos return 0;
527 1.1 christos }
528 1.1 christos
529 1.1 christos /* Reinitialize the processor after a reset. */
530 1.1 christos int
531 1.1 christos cpu_restart (sim_cpu *cpu)
532 1.1 christos {
533 1.1.1.8 christos uint16_t addr;
534 1.1 christos
535 1.1 christos /* Get CPU starting address depending on the CPU mode. */
536 1.1 christos if (cpu->cpu_use_elf_start == 0)
537 1.1 christos {
538 1.1 christos switch ((cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA))
539 1.1 christos {
540 1.1 christos /* Single Chip */
541 1.1 christos default:
542 1.1 christos case 0 :
543 1.1 christos addr = memory_read16 (cpu, 0xFFFE);
544 1.1 christos break;
545 1.1 christos
546 1.1 christos /* Expanded Multiplexed */
547 1.1 christos case M6811_MDA:
548 1.1 christos addr = memory_read16 (cpu, 0xFFFE);
549 1.1 christos break;
550 1.1 christos
551 1.1 christos /* Special Bootstrap */
552 1.1 christos case M6811_SMOD:
553 1.1 christos addr = 0;
554 1.1 christos break;
555 1.1 christos
556 1.1 christos /* Factory Test */
557 1.1 christos case M6811_MDA | M6811_SMOD:
558 1.1 christos addr = memory_read16 (cpu, 0xFFFE);
559 1.1 christos break;
560 1.1 christos }
561 1.1 christos }
562 1.1 christos else
563 1.1 christos {
564 1.1 christos addr = cpu->cpu_elf_start;
565 1.1 christos }
566 1.1 christos
567 1.1 christos /* Setup the processor registers. */
568 1.1 christos cpu->cpu_insn_pc = addr;
569 1.1 christos cpu->cpu_regs.pc = addr;
570 1.1 christos cpu->cpu_regs.ccr = M6811_X_BIT | M6811_I_BIT | M6811_S_BIT;
571 1.1 christos cpu->cpu_absolute_cycle = 0;
572 1.1 christos cpu->cpu_is_initialized = 1;
573 1.1 christos cpu->cpu_current_cycle = 0;
574 1.1 christos
575 1.1 christos cpu_call (cpu, addr);
576 1.1 christos
577 1.1 christos return 0;
578 1.1 christos }
579 1.1 christos
580 1.1 christos void
581 1.1 christos print_io_reg_desc (SIM_DESC sd, io_reg_desc *desc, int val, int mode)
582 1.1 christos {
583 1.1 christos while (desc->mask)
584 1.1 christos {
585 1.1 christos if (val & desc->mask)
586 1.1 christos sim_io_printf (sd, "%s",
587 1.1 christos mode == 0 ? desc->short_name : desc->long_name);
588 1.1 christos desc++;
589 1.1 christos }
590 1.1 christos }
591 1.1 christos
592 1.1 christos void
593 1.1 christos print_io_byte (SIM_DESC sd, const char *name, io_reg_desc *desc,
594 1.1.1.8 christos uint8_t val, uint16_t addr)
595 1.1 christos {
596 1.1 christos sim_io_printf (sd, " %-9.9s @ 0x%04x 0x%02x ", name, addr, val);
597 1.1 christos if (desc)
598 1.1 christos print_io_reg_desc (sd, desc, val, 0);
599 1.1 christos }
600 1.1 christos
601 1.1 christos void
602 1.1 christos print_io_word (SIM_DESC sd, const char *name, io_reg_desc *desc,
603 1.1.1.8 christos uint16_t val, uint16_t addr)
604 1.1 christos {
605 1.1 christos sim_io_printf (sd, " %-9.9s @ 0x%04x 0x%04x ", name, addr, val);
606 1.1 christos if (desc)
607 1.1 christos print_io_reg_desc (sd, desc, val, 0);
608 1.1 christos }
609 1.1 christos
610 1.1 christos void
611 1.1.1.8 christos cpu_ccr_update_tst8 (sim_cpu *cpu, uint8_t val)
612 1.1 christos {
613 1.1.1.5 christos cpu_set_ccr_V (cpu, 0);
614 1.1.1.5 christos cpu_set_ccr_N (cpu, val & 0x80 ? 1 : 0);
615 1.1.1.5 christos cpu_set_ccr_Z (cpu, val == 0 ? 1 : 0);
616 1.1 christos }
617 1.1 christos
618 1.1 christos
619 1.1.1.8 christos uint16_t
620 1.1 christos cpu_fetch_relbranch (sim_cpu *cpu)
621 1.1 christos {
622 1.1.1.8 christos uint16_t addr = (uint16_t) cpu_fetch8 (cpu);
623 1.1 christos
624 1.1 christos if (addr & 0x0080)
625 1.1 christos {
626 1.1 christos addr |= 0xFF00;
627 1.1 christos }
628 1.1 christos addr += cpu->cpu_regs.pc;
629 1.1 christos return addr;
630 1.1 christos }
631 1.1 christos
632 1.1.1.8 christos uint16_t
633 1.1 christos cpu_fetch_relbranch16 (sim_cpu *cpu)
634 1.1 christos {
635 1.1.1.8 christos uint16_t addr = cpu_fetch16 (cpu);
636 1.1 christos
637 1.1 christos addr += cpu->cpu_regs.pc;
638 1.1 christos return addr;
639 1.1 christos }
640 1.1 christos
641 1.1 christos /* Push all the CPU registers (when an interruption occurs). */
642 1.1 christos void
643 1.1 christos cpu_push_all (sim_cpu *cpu)
644 1.1 christos {
645 1.1 christos if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
646 1.1 christos {
647 1.1 christos cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.pc);
648 1.1 christos cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.iy);
649 1.1 christos cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.ix);
650 1.1 christos cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.d);
651 1.1 christos cpu_m68hc11_push_uint8 (cpu, cpu->cpu_regs.ccr);
652 1.1 christos }
653 1.1 christos else
654 1.1 christos {
655 1.1 christos cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.pc);
656 1.1 christos cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.iy);
657 1.1 christos cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.ix);
658 1.1 christos cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.d);
659 1.1 christos cpu_m68hc12_push_uint8 (cpu, cpu->cpu_regs.ccr);
660 1.1 christos }
661 1.1 christos }
662 1.1 christos
663 1.1 christos /* Simulation of the dbcc/ibcc/tbcc 68HC12 conditional branch operations. */
664 1.1 christos void
665 1.1.1.5 christos cpu_dbcc (sim_cpu *cpu)
666 1.1 christos {
667 1.1.1.8 christos uint8_t code;
668 1.1.1.8 christos uint16_t addr;
669 1.1.1.8 christos uint16_t inc;
670 1.1.1.8 christos uint16_t reg;
671 1.1 christos
672 1.1 christos code = cpu_fetch8 (cpu);
673 1.1 christos switch (code & 0xc0)
674 1.1 christos {
675 1.1 christos case 0x80: /* ibcc */
676 1.1 christos inc = 1;
677 1.1 christos break;
678 1.1 christos case 0x40: /* tbcc */
679 1.1 christos inc = 0;
680 1.1 christos break;
681 1.1 christos case 0: /* dbcc */
682 1.1 christos inc = -1;
683 1.1 christos break;
684 1.1 christos default:
685 1.1 christos abort ();
686 1.1 christos break;
687 1.1 christos }
688 1.1 christos
689 1.1 christos addr = cpu_fetch8 (cpu);
690 1.1 christos if (code & 0x10)
691 1.1 christos addr |= 0xff00;
692 1.1 christos
693 1.1 christos addr += cpu_get_pc (cpu);
694 1.1 christos reg = cpu_get_src_reg (cpu, code & 0x07);
695 1.1 christos reg += inc;
696 1.1 christos
697 1.1 christos /* Branch according to register value. */
698 1.1 christos if ((reg != 0 && (code & 0x20)) || (reg == 0 && !(code & 0x20)))
699 1.1 christos {
700 1.1 christos cpu_set_pc (cpu, addr);
701 1.1 christos }
702 1.1 christos cpu_set_dst_reg (cpu, code & 0x07, reg);
703 1.1 christos }
704 1.1 christos
705 1.1 christos void
706 1.1.1.8 christos cpu_exg (sim_cpu *cpu, uint8_t code)
707 1.1 christos {
708 1.1.1.8 christos uint8_t r1, r2;
709 1.1.1.8 christos uint16_t src1;
710 1.1.1.8 christos uint16_t src2;
711 1.1 christos
712 1.1 christos r1 = (code >> 4) & 0x07;
713 1.1 christos r2 = code & 0x07;
714 1.1 christos if (code & 0x80)
715 1.1 christos {
716 1.1 christos src1 = cpu_get_src_reg (cpu, r1);
717 1.1 christos src2 = cpu_get_src_reg (cpu, r2);
718 1.1 christos if (r2 == 1 || r2 == 2)
719 1.1 christos src2 |= 0xff00;
720 1.1 christos
721 1.1 christos cpu_set_dst_reg (cpu, r2, src1);
722 1.1 christos cpu_set_dst_reg (cpu, r1, src2);
723 1.1 christos }
724 1.1 christos else
725 1.1 christos {
726 1.1 christos src1 = cpu_get_src_reg (cpu, r1);
727 1.1 christos
728 1.1 christos /* Sign extend the 8-bit registers (A, B, CCR). */
729 1.1 christos if ((r1 == 0 || r1 == 1 || r1 == 2) && (src1 & 0x80))
730 1.1 christos src1 |= 0xff00;
731 1.1 christos
732 1.1 christos cpu_set_dst_reg (cpu, r2, src1);
733 1.1 christos }
734 1.1 christos }
735 1.1 christos
736 1.1 christos /* Handle special instructions. */
737 1.1 christos void
738 1.1 christos cpu_special (sim_cpu *cpu, enum M6811_Special special)
739 1.1 christos {
740 1.1 christos switch (special)
741 1.1 christos {
742 1.1 christos case M6811_RTI:
743 1.1 christos {
744 1.1.1.8 christos uint8_t ccr;
745 1.1 christos
746 1.1 christos ccr = cpu_m68hc11_pop_uint8 (cpu);
747 1.1 christos cpu_set_ccr (cpu, ccr);
748 1.1 christos cpu_set_d (cpu, cpu_m68hc11_pop_uint16 (cpu));
749 1.1 christos cpu_set_x (cpu, cpu_m68hc11_pop_uint16 (cpu));
750 1.1 christos cpu_set_y (cpu, cpu_m68hc11_pop_uint16 (cpu));
751 1.1 christos cpu_set_pc (cpu, cpu_m68hc11_pop_uint16 (cpu));
752 1.1 christos cpu_return (cpu);
753 1.1 christos break;
754 1.1 christos }
755 1.1 christos
756 1.1 christos case M6812_RTI:
757 1.1 christos {
758 1.1.1.8 christos uint8_t ccr;
759 1.1 christos
760 1.1 christos ccr = cpu_m68hc12_pop_uint8 (cpu);
761 1.1 christos cpu_set_ccr (cpu, ccr);
762 1.1 christos cpu_set_d (cpu, cpu_m68hc12_pop_uint16 (cpu));
763 1.1 christos cpu_set_x (cpu, cpu_m68hc12_pop_uint16 (cpu));
764 1.1 christos cpu_set_y (cpu, cpu_m68hc12_pop_uint16 (cpu));
765 1.1 christos cpu_set_pc (cpu, cpu_m68hc12_pop_uint16 (cpu));
766 1.1 christos cpu_return (cpu);
767 1.1 christos break;
768 1.1 christos }
769 1.1 christos
770 1.1 christos case M6811_WAI:
771 1.1 christos /* In the ELF-start mode, we are in a special mode where
772 1.1 christos the WAI corresponds to an exit. */
773 1.1 christos if (cpu->cpu_use_elf_start)
774 1.1 christos {
775 1.1 christos cpu_set_pc (cpu, cpu->cpu_insn_pc);
776 1.1 christos sim_engine_halt (CPU_STATE (cpu), cpu,
777 1.1 christos NULL, NULL_CIA, sim_exited,
778 1.1 christos cpu_get_d (cpu));
779 1.1 christos return;
780 1.1 christos }
781 1.1 christos /* SCz: not correct... */
782 1.1 christos cpu_push_all (cpu);
783 1.1 christos break;
784 1.1 christos
785 1.1 christos case M6811_SWI:
786 1.1 christos interrupts_raise (&cpu->cpu_interrupts, M6811_INT_SWI);
787 1.1 christos interrupts_process (&cpu->cpu_interrupts);
788 1.1 christos break;
789 1.1 christos
790 1.1 christos case M6811_EMUL_SYSCALL:
791 1.1 christos case M6811_ILLEGAL:
792 1.1 christos if (cpu->cpu_emul_syscall)
793 1.1 christos {
794 1.1.1.8 christos uint8_t op = memory_read8 (cpu,
795 1.1 christos cpu_get_pc (cpu) - 1);
796 1.1 christos if (op == 0x41)
797 1.1 christos {
798 1.1 christos cpu_set_pc (cpu, cpu->cpu_insn_pc);
799 1.1 christos sim_engine_halt (CPU_STATE (cpu), cpu,
800 1.1 christos NULL, NULL_CIA, sim_exited,
801 1.1 christos cpu_get_d (cpu));
802 1.1 christos return;
803 1.1 christos }
804 1.1 christos else
805 1.1 christos {
806 1.1 christos emul_os (op, cpu);
807 1.1 christos }
808 1.1 christos return;
809 1.1 christos }
810 1.1 christos
811 1.1 christos interrupts_raise (&cpu->cpu_interrupts, M6811_INT_ILLEGAL);
812 1.1 christos interrupts_process (&cpu->cpu_interrupts);
813 1.1 christos break;
814 1.1 christos
815 1.1 christos case M6811_TEST:
816 1.1 christos case M6812_BGND:
817 1.1 christos {
818 1.1 christos SIM_DESC sd;
819 1.1 christos
820 1.1 christos sd = CPU_STATE (cpu);
821 1.1 christos
822 1.1 christos /* Breakpoint instruction if we are under gdb. */
823 1.1 christos if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
824 1.1 christos {
825 1.1 christos cpu->cpu_regs.pc --;
826 1.1 christos sim_engine_halt (CPU_STATE (cpu), cpu,
827 1.1 christos 0, cpu_get_pc (cpu), sim_stopped,
828 1.1 christos SIM_SIGTRAP);
829 1.1 christos }
830 1.1 christos /* else this is a nop but not in test factory mode. */
831 1.1 christos break;
832 1.1 christos }
833 1.1 christos
834 1.1 christos case M6812_IDIVS:
835 1.1 christos {
836 1.1.1.8 christos int32_t src1 = (int16_t) cpu_get_d (cpu);
837 1.1.1.8 christos int32_t src2 = (int16_t) cpu_get_x (cpu);
838 1.1 christos
839 1.1 christos if (src2 == 0)
840 1.1 christos {
841 1.1 christos cpu_set_ccr_C (cpu, 1);
842 1.1 christos }
843 1.1 christos else
844 1.1 christos {
845 1.1 christos cpu_set_d (cpu, src1 % src2);
846 1.1 christos src1 = src1 / src2;
847 1.1 christos cpu_set_x (cpu, src1);
848 1.1 christos cpu_set_ccr_C (cpu, 0);
849 1.1 christos cpu_set_ccr_Z (cpu, src1 == 0);
850 1.1 christos cpu_set_ccr_N (cpu, src1 & 0x8000);
851 1.1 christos cpu_set_ccr_V (cpu, src1 >= 32768 || src1 < -32768);
852 1.1 christos }
853 1.1 christos }
854 1.1 christos break;
855 1.1 christos
856 1.1 christos case M6812_EDIV:
857 1.1 christos {
858 1.1.1.8 christos uint32_t src1 = (uint32_t) cpu_get_x (cpu);
859 1.1.1.8 christos uint32_t src2 = (uint32_t) (cpu_get_y (cpu) << 16)
860 1.1.1.8 christos | (uint32_t) (cpu_get_d (cpu));
861 1.1 christos
862 1.1 christos if (src1 == 0)
863 1.1 christos {
864 1.1 christos cpu_set_ccr_C (cpu, 1);
865 1.1 christos }
866 1.1 christos else
867 1.1 christos {
868 1.1 christos cpu_set_ccr_C (cpu, 0);
869 1.1 christos cpu_set_d (cpu, src2 % src1);
870 1.1 christos src2 = src2 / src1;
871 1.1 christos cpu_set_y (cpu, src2);
872 1.1 christos cpu_set_ccr_Z (cpu, src2 == 0);
873 1.1 christos cpu_set_ccr_N (cpu, (src2 & 0x8000) != 0);
874 1.1 christos cpu_set_ccr_V (cpu, (src2 & 0xffff0000) != 0);
875 1.1 christos }
876 1.1 christos }
877 1.1 christos break;
878 1.1 christos
879 1.1 christos case M6812_EDIVS:
880 1.1 christos {
881 1.1.1.8 christos int32_t src1 = (int16_t) cpu_get_x (cpu);
882 1.1.1.8 christos int32_t src2 = (uint32_t) (cpu_get_y (cpu) << 16)
883 1.1.1.8 christos | (uint32_t) (cpu_get_d (cpu));
884 1.1 christos
885 1.1 christos if (src1 == 0)
886 1.1 christos {
887 1.1 christos cpu_set_ccr_C (cpu, 1);
888 1.1 christos }
889 1.1 christos else
890 1.1 christos {
891 1.1 christos cpu_set_ccr_C (cpu, 0);
892 1.1 christos cpu_set_d (cpu, src2 % src1);
893 1.1 christos src2 = src2 / src1;
894 1.1 christos cpu_set_y (cpu, src2);
895 1.1 christos cpu_set_ccr_Z (cpu, src2 == 0);
896 1.1 christos cpu_set_ccr_N (cpu, (src2 & 0x8000) != 0);
897 1.1 christos cpu_set_ccr_V (cpu, src2 > 32767 || src2 < -32768);
898 1.1 christos }
899 1.1 christos }
900 1.1 christos break;
901 1.1 christos
902 1.1 christos case M6812_EMULS:
903 1.1 christos {
904 1.1.1.8 christos int32_t src1, src2;
905 1.1 christos
906 1.1.1.8 christos src1 = (int16_t) cpu_get_d (cpu);
907 1.1.1.8 christos src2 = (int16_t) cpu_get_y (cpu);
908 1.1 christos src1 = src1 * src2;
909 1.1 christos cpu_set_d (cpu, src1 & 0x0ffff);
910 1.1 christos cpu_set_y (cpu, src1 >> 16);
911 1.1 christos cpu_set_ccr_Z (cpu, src1 == 0);
912 1.1 christos cpu_set_ccr_N (cpu, (src1 & 0x80000000) != 0);
913 1.1 christos cpu_set_ccr_C (cpu, (src1 & 0x00008000) != 0);
914 1.1 christos }
915 1.1 christos break;
916 1.1 christos
917 1.1 christos case M6812_EMACS:
918 1.1 christos {
919 1.1.1.8 christos int32_t src1, src2;
920 1.1.1.8 christos uint16_t addr;
921 1.1 christos
922 1.1 christos addr = cpu_fetch16 (cpu);
923 1.1.1.8 christos src1 = (int16_t) memory_read16 (cpu, cpu_get_x (cpu));
924 1.1.1.8 christos src2 = (int16_t) memory_read16 (cpu, cpu_get_y (cpu));
925 1.1 christos src1 = src1 * src2;
926 1.1.1.8 christos src2 = (((uint32_t) memory_read16 (cpu, addr)) << 16)
927 1.1.1.8 christos | (uint32_t) memory_read16 (cpu, addr + 2);
928 1.1 christos
929 1.1 christos memory_write16 (cpu, addr, (src1 + src2) >> 16);
930 1.1 christos memory_write16 (cpu, addr + 2, (src1 + src2));
931 1.1 christos
932 1.1 christos
933 1.1 christos }
934 1.1 christos break;
935 1.1 christos
936 1.1 christos case M6812_CALL:
937 1.1 christos {
938 1.1.1.8 christos uint8_t page;
939 1.1.1.8 christos uint16_t addr;
940 1.1 christos
941 1.1 christos addr = cpu_fetch16 (cpu);
942 1.1 christos page = cpu_fetch8 (cpu);
943 1.1 christos
944 1.1 christos cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu));
945 1.1 christos cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu));
946 1.1 christos
947 1.1 christos cpu_set_page (cpu, page);
948 1.1 christos cpu_set_pc (cpu, addr);
949 1.1 christos }
950 1.1 christos break;
951 1.1 christos
952 1.1 christos case M6812_CALL_INDIRECT:
953 1.1 christos {
954 1.1.1.8 christos uint8_t code;
955 1.1.1.8 christos uint16_t addr;
956 1.1.1.8 christos uint8_t page;
957 1.1 christos
958 1.1 christos code = memory_read8 (cpu, cpu_get_pc (cpu));
959 1.1 christos /* Indirect addressing call has the page specified in the
960 1.1 christos memory location pointed to by the address. */
961 1.1 christos if ((code & 0xE3) == 0xE3)
962 1.1 christos {
963 1.1 christos addr = cpu_get_indexed_operand_addr (cpu, 0);
964 1.1 christos page = memory_read8 (cpu, addr + 2);
965 1.1 christos addr = memory_read16 (cpu, addr);
966 1.1 christos }
967 1.1 christos else
968 1.1 christos {
969 1.1 christos /* Otherwise, page is in the opcode. */
970 1.1 christos addr = cpu_get_indexed_operand16 (cpu, 0);
971 1.1 christos page = cpu_fetch8 (cpu);
972 1.1 christos }
973 1.1 christos cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu));
974 1.1 christos cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu));
975 1.1 christos cpu_set_page (cpu, page);
976 1.1 christos cpu_set_pc (cpu, addr);
977 1.1 christos }
978 1.1 christos break;
979 1.1 christos
980 1.1 christos case M6812_RTC:
981 1.1 christos {
982 1.1.1.8 christos uint8_t page = cpu_m68hc12_pop_uint8 (cpu);
983 1.1.1.8 christos uint16_t addr = cpu_m68hc12_pop_uint16 (cpu);
984 1.1 christos
985 1.1 christos cpu_set_page (cpu, page);
986 1.1 christos cpu_set_pc (cpu, addr);
987 1.1 christos }
988 1.1 christos break;
989 1.1 christos
990 1.1 christos case M6812_ETBL:
991 1.1 christos default:
992 1.1 christos sim_engine_halt (CPU_STATE (cpu), cpu, NULL,
993 1.1 christos cpu_get_pc (cpu), sim_stopped,
994 1.1 christos SIM_SIGILL);
995 1.1 christos break;
996 1.1 christos }
997 1.1 christos }
998 1.1 christos
999 1.1 christos
1000 1.1 christos void
1001 1.1 christos cpu_single_step (sim_cpu *cpu)
1002 1.1 christos {
1003 1.1 christos cpu->cpu_current_cycle = 0;
1004 1.1 christos cpu->cpu_insn_pc = cpu_get_pc (cpu);
1005 1.1 christos
1006 1.1 christos /* Handle the pending interrupts. If an interrupt is handled,
1007 1.1 christos treat this as an single step. */
1008 1.1 christos if (interrupts_process (&cpu->cpu_interrupts))
1009 1.1 christos {
1010 1.1 christos cpu->cpu_absolute_cycle += cpu->cpu_current_cycle;
1011 1.1 christos return;
1012 1.1 christos }
1013 1.1 christos
1014 1.1 christos /* printf("PC = 0x%04x\n", cpu_get_pc (cpu));*/
1015 1.1 christos cpu->cpu_interpretor (cpu);
1016 1.1 christos cpu->cpu_absolute_cycle += cpu->cpu_current_cycle;
1017 1.1 christos }
1018 1.1 christos
1019 1.1 christos /* VARARGS */
1020 1.1 christos void
1021 1.1 christos sim_memory_error (sim_cpu *cpu, SIM_SIGNAL excep,
1022 1.1.1.8 christos uint16_t addr, const char *message, ...)
1023 1.1 christos {
1024 1.1 christos char buf[1024];
1025 1.1 christos va_list args;
1026 1.1 christos
1027 1.1 christos va_start (args, message);
1028 1.1 christos vsprintf (buf, message, args);
1029 1.1 christos va_end (args);
1030 1.1 christos
1031 1.1 christos sim_io_printf (CPU_STATE (cpu), "%s\n", buf);
1032 1.1 christos cpu_memory_exception (cpu, excep, addr, buf);
1033 1.1 christos }
1034 1.1 christos
1035 1.1 christos
1036 1.1 christos void
1037 1.1 christos cpu_memory_exception (sim_cpu *cpu, SIM_SIGNAL excep,
1038 1.1.1.8 christos uint16_t addr, const char *message)
1039 1.1 christos {
1040 1.1 christos if (cpu->cpu_running == 0)
1041 1.1 christos return;
1042 1.1 christos
1043 1.1 christos cpu_set_pc (cpu, cpu->cpu_insn_pc);
1044 1.1 christos sim_engine_halt (CPU_STATE (cpu), cpu, NULL,
1045 1.1 christos cpu_get_pc (cpu), sim_stopped, excep);
1046 1.1 christos
1047 1.1 christos #if 0
1048 1.1 christos cpu->mem_exception = excep;
1049 1.1 christos cpu->fault_addr = addr;
1050 1.1 christos cpu->fault_msg = strdup (message);
1051 1.1 christos
1052 1.1 christos if (cpu->cpu_use_handler)
1053 1.1 christos {
1054 1.1 christos longjmp (&cpu->cpu_exception_handler, 1);
1055 1.1 christos }
1056 1.1 christos (* cpu->callback->printf_filtered)
1057 1.1 christos (cpu->callback, "Fault at 0x%04x: %s\n", addr, message);
1058 1.1 christos #endif
1059 1.1 christos }
1060 1.1 christos
1061 1.1 christos void
1062 1.1 christos cpu_info (SIM_DESC sd, sim_cpu *cpu)
1063 1.1 christos {
1064 1.1 christos sim_io_printf (sd, "CPU info:\n");
1065 1.1 christos sim_io_printf (sd, " Absolute cycle: %s\n",
1066 1.1 christos cycle_to_string (cpu, cpu->cpu_absolute_cycle,
1067 1.1 christos PRINT_TIME | PRINT_CYCLE));
1068 1.1 christos
1069 1.1 christos sim_io_printf (sd, " Syscall emulation: %s\n",
1070 1.1 christos cpu->cpu_emul_syscall ? "yes, via 0xcd <n>" : "no");
1071 1.1 christos sim_io_printf (sd, " Memory errors detection: %s\n",
1072 1.1 christos cpu->cpu_check_memory ? "yes" : "no");
1073 1.1 christos sim_io_printf (sd, " Stop on interrupt: %s\n",
1074 1.1 christos cpu->cpu_stop_on_interrupt ? "yes" : "no");
1075 1.1 christos }
1076 1.1 christos
1077