]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m68hc11/interp.c
Switch the license of all files explicitly copyright the FSF
[thirdparty/binutils-gdb.git] / sim / m68hc11 / interp.c
CommitLineData
5abb9efa 1/* interp.c -- Simulator for Motorola 68HC11/68HC12
6aba47ca 2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2007
84b11e2e 3 Free Software Foundation, Inc.
63f36def 4 Written by Stephane Carrez (stcarrez@nerim.fr)
e0709f50
AC
5
6This file is part of GDB, the GNU debugger.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
4744ac1b
JB
10the Free Software Foundation; either version 3 of the License, or
11(at your option) any later version.
e0709f50
AC
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
4744ac1b
JB
18You should have received a copy of the GNU General Public License
19along with this program. If not, see <http://www.gnu.org/licenses/>. */
e0709f50
AC
20
21#include "sim-main.h"
22#include "sim-assert.h"
23#include "sim-hw.h"
24#include "sim-options.h"
25#include "hw-tree.h"
26#include "hw-device.h"
27#include "hw-ports.h"
77342e5e 28#include "elf32-m68hc1x.h"
e0709f50
AC
29
30#ifndef MONITOR_BASE
31# define MONITOR_BASE (0x0C000)
32# define MONITOR_SIZE (0x04000)
33#endif
34
35static void sim_get_info (SIM_DESC sd, char *cmd);
36
37
38char *interrupt_names[] = {
39 "reset",
40 "nmi",
41 "int",
42 NULL
43};
44
45#ifndef INLINE
46#if defined(__GNUC__) && defined(__OPTIMIZE__)
47#define INLINE __inline__
48#else
49#define INLINE
50#endif
51#endif
52
53struct sim_info_list
54{
55 const char *name;
56 const char *device;
57};
58
81e09ed8 59struct sim_info_list dev_list_68hc11[] = {
e0709f50
AC
60 {"cpu", "/m68hc11"},
61 {"timer", "/m68hc11/m68hc11tim"},
62 {"sio", "/m68hc11/m68hc11sio"},
63 {"spi", "/m68hc11/m68hc11spi"},
64 {"eeprom", "/m68hc11/m68hc11eepr"},
65 {0, 0}
66};
67
81e09ed8
SC
68struct sim_info_list dev_list_68hc12[] = {
69 {"cpu", "/m68hc12"},
70 {"timer", "/m68hc12/m68hc12tim"},
71 {"sio", "/m68hc12/m68hc12sio"},
72 {"spi", "/m68hc12/m68hc12spi"},
73 {"eeprom", "/m68hc12/m68hc12eepr"},
74 {0, 0}
75};
76
77/* Cover function of sim_state_free to free the cpu buffers as well. */
78
79static void
80free_state (SIM_DESC sd)
81{
82 if (STATE_MODULES (sd) != NULL)
83 sim_module_uninstall (sd);
84
85 sim_state_free (sd);
86}
87
e0709f50
AC
88/* Give some information about the simulator. */
89static void
90sim_get_info (SIM_DESC sd, char *cmd)
91{
92 sim_cpu *cpu;
93
81e09ed8 94 cpu = STATE_CPU (sd, 0);
e0709f50
AC
95 if (cmd != 0 && (cmd[0] == ' ' || cmd[0] == '-'))
96 {
97 int i;
98 struct hw *hw_dev;
81e09ed8
SC
99 struct sim_info_list *dev_list;
100 const struct bfd_arch_info *arch;
101
102 arch = STATE_ARCHITECTURE (sd);
e0709f50
AC
103 cmd++;
104
81e09ed8
SC
105 if (arch->arch == bfd_arch_m68hc11)
106 dev_list = dev_list_68hc11;
107 else
108 dev_list = dev_list_68hc12;
109
e0709f50
AC
110 for (i = 0; dev_list[i].name; i++)
111 if (strcmp (cmd, dev_list[i].name) == 0)
112 break;
113
114 if (dev_list[i].name == 0)
115 {
116 sim_io_eprintf (sd, "Device '%s' not found.\n", cmd);
117 sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
118 return;
119 }
120 hw_dev = sim_hw_parse (sd, dev_list[i].device);
121 if (hw_dev == 0)
122 {
123 sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
124 return;
125 }
126 hw_ioctl (hw_dev, 23, 0);
127 return;
128 }
129
e0709f50
AC
130 cpu_info (sd, cpu);
131 interrupts_info (sd, &cpu->cpu_interrupts);
132}
133
134
135void
136sim_board_reset (SIM_DESC sd)
137{
138 struct hw *hw_cpu;
139 sim_cpu *cpu;
81e09ed8
SC
140 const struct bfd_arch_info *arch;
141 const char *cpu_type;
e0709f50
AC
142
143 cpu = STATE_CPU (sd, 0);
81e09ed8
SC
144 arch = STATE_ARCHITECTURE (sd);
145
e0709f50 146 /* hw_cpu = sim_hw_parse (sd, "/"); */
81e09ed8
SC
147 if (arch->arch == bfd_arch_m68hc11)
148 {
149 cpu->cpu_type = CPU_M6811;
150 cpu_type = "/m68hc11";
151 }
152 else
153 {
154 cpu->cpu_type = CPU_M6812;
155 cpu_type = "/m68hc12";
156 }
157
158 hw_cpu = sim_hw_parse (sd, cpu_type);
e0709f50
AC
159 if (hw_cpu == 0)
160 {
81e09ed8 161 sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
e0709f50
AC
162 return;
163 }
164
165 cpu_reset (cpu);
166 hw_port_event (hw_cpu, 3, 0);
167 cpu_restart (cpu);
168}
169
39762100 170static int
81e09ed8
SC
171sim_hw_configure (SIM_DESC sd)
172{
173 const struct bfd_arch_info *arch;
174 struct hw *device_tree;
81e09ed8
SC
175 sim_cpu *cpu;
176
177 arch = STATE_ARCHITECTURE (sd);
178 if (arch == 0)
179 return 0;
180
181 cpu = STATE_CPU (sd, 0);
182 cpu->cpu_configured_arch = arch;
183 device_tree = sim_hw_parse (sd, "/");
184 if (arch->arch == bfd_arch_m68hc11)
185 {
186 cpu->cpu_interpretor = cpu_interp_m6811;
187 if (hw_tree_find_property (device_tree, "/m68hc11/reg") == 0)
188 {
189 /* Allocate core managed memory */
190
191 /* the monitor */
192 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
193 /* MONITOR_BASE, MONITOR_SIZE */
194 0x8000, M6811_RAM_LEVEL, 0x8000);
195 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
196 M6811_RAM_LEVEL);
197 sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
77342e5e
SC
198 if (cpu->bank_start < cpu->bank_end)
199 {
200 sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
201 cpu->bank_virtual, M6811_RAM_LEVEL);
202 sim_hw_parse (sd, "/m68hc11/use_bank 1");
203 }
81e09ed8 204 }
77342e5e
SC
205 if (cpu->cpu_start_mode)
206 {
207 sim_hw_parse (sd, "/m68hc11/mode %s", cpu->cpu_start_mode);
208 }
81e09ed8
SC
209 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11sio/reg") == 0)
210 {
211 sim_hw_parse (sd, "/m68hc11/m68hc11sio/reg 0x2b 0x5");
212 sim_hw_parse (sd, "/m68hc11/m68hc11sio/backend stdio");
213 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11sio");
214 }
215 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11tim/reg") == 0)
216 {
217 /* M68hc11 Timer configuration. */
218 sim_hw_parse (sd, "/m68hc11/m68hc11tim/reg 0x1b 0x5");
219 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11tim");
827ec39a 220 sim_hw_parse (sd, "/m68hc11 > capture capture /m68hc11/m68hc11tim");
81e09ed8
SC
221 }
222
223 /* Create the SPI device. */
224 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11spi/reg") == 0)
225 {
226 sim_hw_parse (sd, "/m68hc11/m68hc11spi/reg 0x28 0x3");
227 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11spi");
228 }
229 if (hw_tree_find_property (device_tree, "/m68hc11/nvram/reg") == 0)
230 {
231 /* M68hc11 persistent ram configuration. */
232 sim_hw_parse (sd, "/m68hc11/nvram/reg 0x0 256");
233 sim_hw_parse (sd, "/m68hc11/nvram/file m68hc11.ram");
234 sim_hw_parse (sd, "/m68hc11/nvram/mode save-modified");
235 /*sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/pram"); */
236 }
237 if (hw_tree_find_property (device_tree, "/m68hc11/m68hc11eepr/reg") == 0)
238 {
239 sim_hw_parse (sd, "/m68hc11/m68hc11eepr/reg 0xb000 512");
240 sim_hw_parse (sd, "/m68hc11 > cpu-reset reset /m68hc11/m68hc11eepr");
241 }
dcceded2
SC
242 sim_hw_parse (sd, "/m68hc11 > port-a cpu-write-port /m68hc11");
243 sim_hw_parse (sd, "/m68hc11 > port-b cpu-write-port /m68hc11");
244 sim_hw_parse (sd, "/m68hc11 > port-c cpu-write-port /m68hc11");
245 sim_hw_parse (sd, "/m68hc11 > port-d cpu-write-port /m68hc11");
827ec39a 246 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc11");
81e09ed8
SC
247 }
248 else
249 {
250 cpu->cpu_interpretor = cpu_interp_m6812;
251 if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
252 {
253 /* Allocate core external memory. */
254 sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
77342e5e 255 0x8000, M6811_RAM_LEVEL, 0x8000);
81e09ed8
SC
256 sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
257 M6811_RAM_LEVEL);
77342e5e
SC
258 if (cpu->bank_start < cpu->bank_end)
259 {
260 sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
261 cpu->bank_virtual, M6811_RAM_LEVEL);
262 sim_hw_parse (sd, "/m68hc12/use_bank 1");
263 }
81e09ed8
SC
264 sim_hw_parse (sd, "/m68hc12/reg 0x0 0x3FF");
265 }
266
267 if (!hw_tree_find_property (device_tree, "/m68hc12/m68hc12sio@1/reg"))
268 {
269 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/reg 0xC0 0x8");
270 sim_hw_parse (sd, "/m68hc12/m68hc12sio@1/backend stdio");
271 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12sio@1");
272 }
81e09ed8
SC
273 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12tim/reg") == 0)
274 {
275 /* M68hc11 Timer configuration. */
276 sim_hw_parse (sd, "/m68hc12/m68hc12tim/reg 0x1b 0x5");
277 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12tim");
dcceded2 278 sim_hw_parse (sd, "/m68hc12 > capture capture /m68hc12/m68hc12tim");
81e09ed8
SC
279 }
280
281 /* Create the SPI device. */
282 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12spi/reg") == 0)
283 {
284 sim_hw_parse (sd, "/m68hc12/m68hc12spi/reg 0x28 0x3");
285 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12spi");
286 }
287 if (hw_tree_find_property (device_tree, "/m68hc12/nvram/reg") == 0)
288 {
289 /* M68hc11 persistent ram configuration. */
290 sim_hw_parse (sd, "/m68hc12/nvram/reg 0x2000 8192");
291 sim_hw_parse (sd, "/m68hc12/nvram/file m68hc12.ram");
292 sim_hw_parse (sd, "/m68hc12/nvram/mode save-modified");
293 }
294 if (hw_tree_find_property (device_tree, "/m68hc12/m68hc12eepr/reg") == 0)
295 {
296 sim_hw_parse (sd, "/m68hc12/m68hc12eepr/reg 0x0800 2048");
297 sim_hw_parse (sd, "/m68hc12 > cpu-reset reset /m68hc12/m68hc12eepr");
298 }
827ec39a 299
dcceded2
SC
300 sim_hw_parse (sd, "/m68hc12 > port-a cpu-write-port /m68hc12");
301 sim_hw_parse (sd, "/m68hc12 > port-b cpu-write-port /m68hc12");
302 sim_hw_parse (sd, "/m68hc12 > port-c cpu-write-port /m68hc12");
303 sim_hw_parse (sd, "/m68hc12 > port-d cpu-write-port /m68hc12");
827ec39a 304 cpu->hw_cpu = sim_hw_parse (sd, "/m68hc12");
81e09ed8 305 }
39762100 306 return 1;
81e09ed8
SC
307}
308
77342e5e
SC
309/* Get the memory bank parameters by looking at the global symbols
310 defined by the linker. */
81e09ed8 311static int
77342e5e 312sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
81e09ed8
SC
313{
314 sim_cpu *cpu;
77342e5e
SC
315 long symsize;
316 long symbol_count, i;
317 unsigned size;
318 asymbol** asymbols;
319 asymbol** current;
81e09ed8
SC
320
321 cpu = STATE_CPU (sd, 0);
322
77342e5e
SC
323 symsize = bfd_get_symtab_upper_bound (abfd);
324 if (symsize < 0)
325 {
326 sim_io_eprintf (sd, "Cannot read symbols of program");
327 return 0;
328 }
329 asymbols = (asymbol **) xmalloc (symsize);
330 symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
331 if (symbol_count < 0)
332 {
333 sim_io_eprintf (sd, "Cannot read symbols of program");
334 return 0;
335 }
336
337 size = 0;
338 for (i = 0, current = asymbols; i < symbol_count; i++, current++)
339 {
340 const char* name = bfd_asymbol_name (*current);
341
342 if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
343 {
344 cpu->bank_start = bfd_asymbol_value (*current);
345 }
346 else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
347 {
348 size = bfd_asymbol_value (*current);
349 }
350 else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
351 {
352 cpu->bank_virtual = bfd_asymbol_value (*current);
353 }
354 }
355 free (asymbols);
356
357 cpu->bank_end = cpu->bank_start + size;
358 cpu->bank_shift = 0;
359 for (; size > 1; size >>= 1)
360 cpu->bank_shift++;
361
362 return 0;
363}
364
365static int
366sim_prepare_for_program (SIM_DESC sd, bfd* abfd)
367{
368 sim_cpu *cpu;
369 int elf_flags = 0;
370
371 cpu = STATE_CPU (sd, 0);
39762100 372
81e09ed8
SC
373 if (abfd != NULL)
374 {
31c7c532 375 asection *s;
77342e5e
SC
376
377 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
378 elf_flags = elf_elfheader (abfd)->e_flags;
379
81e09ed8 380 cpu->cpu_elf_start = bfd_get_start_address (abfd);
31c7c532
SC
381 /* See if any section sets the reset address */
382 cpu->cpu_use_elf_start = 1;
383 for (s = abfd->sections; s && cpu->cpu_use_elf_start; s = s->next)
384 {
385 if (s->flags & SEC_LOAD)
386 {
387 bfd_size_type size;
388
84b11e2e 389 size = bfd_get_section_size (s);
31c7c532
SC
390 if (size > 0)
391 {
392 bfd_vma lma;
393
394 if (STATE_LOAD_AT_LMA_P (sd))
395 lma = bfd_section_lma (abfd, s);
396 else
397 lma = bfd_section_vma (abfd, s);
398
399 if (lma <= 0xFFFE && lma+size >= 0x10000)
400 cpu->cpu_use_elf_start = 0;
401 }
402 }
403 }
77342e5e
SC
404
405 if (elf_flags & E_M68HC12_BANKS)
406 {
407 if (sim_get_bank_parameters (sd, abfd) != 0)
408 sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
409 }
81e09ed8
SC
410 }
411
77342e5e
SC
412 if (!sim_hw_configure (sd))
413 return SIM_RC_FAIL;
414
81e09ed8
SC
415 /* reset all state information */
416 sim_board_reset (sd);
417
418 return SIM_RC_OK;
419}
420
e0709f50
AC
421SIM_DESC
422sim_open (SIM_OPEN_KIND kind, host_callback *callback,
77342e5e 423 bfd *abfd, char **argv)
e0709f50 424{
e0709f50
AC
425 SIM_DESC sd;
426 sim_cpu *cpu;
e0709f50
AC
427
428 sd = sim_state_alloc (kind, callback);
429 cpu = STATE_CPU (sd, 0);
430
431 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
432
433 /* for compatibility */
434 current_alignment = NONSTRICT_ALIGNMENT;
435 current_target_byte_order = BIG_ENDIAN;
436
437 cpu_initialize (sd, cpu);
438
e0709f50 439 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
81e09ed8
SC
440 {
441 free_state (sd);
442 return 0;
443 }
e0709f50
AC
444
445 /* getopt will print the error message so we just have to exit if this fails.
446 FIXME: Hmmm... in the case of gdb we need getopt to call
447 print_filtered. */
448 if (sim_parse_args (sd, argv) != SIM_RC_OK)
449 {
450 /* Uninstall the modules to avoid memory leaks,
451 file descriptor leaks, etc. */
81e09ed8 452 free_state (sd);
e0709f50
AC
453 return 0;
454 }
455
e0709f50
AC
456 /* Check for/establish the a reference program image. */
457 if (sim_analyze_program (sd,
458 (STATE_PROG_ARGV (sd) != NULL
459 ? *STATE_PROG_ARGV (sd)
460 : NULL), abfd) != SIM_RC_OK)
461 {
81e09ed8 462 free_state (sd);
e0709f50
AC
463 return 0;
464 }
465
466 /* Establish any remaining configuration options. */
467 if (sim_config (sd) != SIM_RC_OK)
468 {
81e09ed8 469 free_state (sd);
e0709f50
AC
470 return 0;
471 }
472
473 if (sim_post_argv_init (sd) != SIM_RC_OK)
474 {
475 /* Uninstall the modules to avoid memory leaks,
476 file descriptor leaks, etc. */
81e09ed8 477 free_state (sd);
e0709f50
AC
478 return 0;
479 }
77342e5e
SC
480 if (sim_prepare_for_program (sd, abfd) != SIM_RC_OK)
481 {
482 free_state (sd);
483 return 0;
484 }
e0709f50
AC
485
486 /* Fudge our descriptor. */
487 return sd;
488}
489
490
491void
492sim_close (SIM_DESC sd, int quitting)
493{
494 /* shut down modules */
495 sim_module_uninstall (sd);
496
497 /* Ensure that any resources allocated through the callback
498 mechanism are released: */
499 sim_io_shutdown (sd);
500
501 /* FIXME - free SD */
81e09ed8 502 sim_state_free (sd);
e0709f50
AC
503 return;
504}
505
506void
507sim_set_profile (int n)
508{
509}
510
511void
512sim_set_profile_size (int n)
513{
514}
515
516/* Generic implementation of sim_engine_run that works within the
517 sim_engine setjmp/longjmp framework. */
518
519void
520sim_engine_run (SIM_DESC sd,
521 int next_cpu_nr, /* ignore */
522 int nr_cpus, /* ignore */
523 int siggnal) /* ignore */
524{
525 sim_cpu *cpu;
526
527 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
528 cpu = STATE_CPU (sd, 0);
529 while (1)
530 {
531 cpu_single_step (cpu);
532
533 /* process any events */
534 if (sim_events_tickn (sd, cpu->cpu_current_cycle))
535 {
536 sim_events_process (sd);
537 }
538 }
539}
540
541int
542sim_trace (SIM_DESC sd)
543{
544 sim_resume (sd, 0, 0);
545 return 1;
546}
547
548void
549sim_info (SIM_DESC sd, int verbose)
550{
81e09ed8
SC
551 const char *cpu_type;
552 const struct bfd_arch_info *arch;
553
00d0c012
SC
554 /* Nothing to do if there is no verbose flag set. */
555 if (verbose == 0 && STATE_VERBOSE_P (sd) == 0)
556 return;
557
81e09ed8
SC
558 arch = STATE_ARCHITECTURE (sd);
559 if (arch->arch == bfd_arch_m68hc11)
560 cpu_type = "68HC11";
561 else
562 cpu_type = "68HC12";
563
e0709f50 564 sim_io_eprintf (sd, "Simulator info:\n");
81e09ed8 565 sim_io_eprintf (sd, " CPU Motorola %s\n", cpu_type);
e0709f50
AC
566 sim_get_info (sd, 0);
567 sim_module_info (sd, verbose || STATE_VERBOSE_P (sd));
568}
569
570SIM_RC
6b4a8935 571sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
e0709f50
AC
572 char **argv, char **env)
573{
81e09ed8 574 return sim_prepare_for_program (sd, abfd);
e0709f50
AC
575}
576
577
578void
579sim_set_callbacks (host_callback *p)
580{
581 /* m6811_callback = p; */
582}
583
584
585int
586sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
587{
588 sim_cpu *cpu;
589 uint16 val;
63f36def 590 int size = 2;
e0709f50
AC
591
592 cpu = STATE_CPU (sd, 0);
593 switch (rn)
594 {
595 case A_REGNUM:
596 val = cpu_get_a (cpu);
63f36def 597 size = 1;
e0709f50
AC
598 break;
599
600 case B_REGNUM:
601 val = cpu_get_b (cpu);
63f36def 602 size = 1;
e0709f50
AC
603 break;
604
605 case D_REGNUM:
606 val = cpu_get_d (cpu);
607 break;
608
609 case X_REGNUM:
610 val = cpu_get_x (cpu);
611 break;
612
613 case Y_REGNUM:
614 val = cpu_get_y (cpu);
615 break;
616
617 case SP_REGNUM:
618 val = cpu_get_sp (cpu);
619 break;
620
621 case PC_REGNUM:
622 val = cpu_get_pc (cpu);
623 break;
624
625 case PSW_REGNUM:
626 val = cpu_get_ccr (cpu);
63f36def
SC
627 size = 1;
628 break;
629
630 case PAGE_REGNUM:
631 val = cpu_get_page (cpu);
632 size = 1;
e0709f50
AC
633 break;
634
e0709f50 635 default:
9830501b 636 val = 0;
e0709f50
AC
637 break;
638 }
00416c6e
SC
639 if (size == 1)
640 {
641 memory[0] = val;
642 }
643 else
644 {
645 memory[0] = val >> 8;
646 memory[1] = val & 0x0FF;
647 }
63f36def 648 return size;
e0709f50
AC
649}
650
651int
652sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
653{
654 uint16 val;
655 sim_cpu *cpu;
656
657 cpu = STATE_CPU (sd, 0);
658
659 val = *memory++;
660 if (length == 2)
661 val = (val << 8) | *memory;
662
663 switch (rn)
664 {
665 case D_REGNUM:
666 cpu_set_d (cpu, val);
667 break;
668
669 case A_REGNUM:
670 cpu_set_a (cpu, val);
63f36def 671 return 1;
e0709f50
AC
672
673 case B_REGNUM:
674 cpu_set_b (cpu, val);
63f36def 675 return 1;
e0709f50
AC
676
677 case X_REGNUM:
678 cpu_set_x (cpu, val);
679 break;
680
681 case Y_REGNUM:
682 cpu_set_y (cpu, val);
683 break;
684
685 case SP_REGNUM:
686 cpu_set_sp (cpu, val);
687 break;
688
689 case PC_REGNUM:
690 cpu_set_pc (cpu, val);
691 break;
692
693 case PSW_REGNUM:
694 cpu_set_ccr (cpu, val);
63f36def
SC
695 return 1;
696
697 case PAGE_REGNUM:
698 cpu_set_page (cpu, val);
699 return 1;
e0709f50 700
e0709f50 701 default:
e0709f50
AC
702 break;
703 }
704
705 return 2;
706}
707
708void
709sim_size (int s)
710{
711 ;
712}
713
714void
715sim_do_command (SIM_DESC sd, char *cmd)
716{
717 char *mm_cmd = "memory-map";
718 char *int_cmd = "interrupt";
81e09ed8 719 sim_cpu *cpu;
e0709f50 720
81e09ed8 721 cpu = STATE_CPU (sd, 0);
e0709f50
AC
722 /* Commands available from GDB: */
723 if (sim_args_command (sd, cmd) != SIM_RC_OK)
724 {
725 if (strncmp (cmd, "info", sizeof ("info") - 1) == 0)
726 sim_get_info (sd, &cmd[4]);
e0709f50
AC
727 else if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
728 sim_io_eprintf (sd,
729 "`memory-map' command replaced by `sim memory'\n");
730 else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
731 sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
732 else
733 sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
734 }
81e09ed8
SC
735
736 /* If the architecture changed, re-configure. */
737 if (STATE_ARCHITECTURE (sd) != cpu->cpu_configured_arch)
738 sim_hw_configure (sd);
e0709f50 739}
00d0c012
SC
740
741/* Halt the simulator after just one instruction */
742
743static void
744has_stepped (SIM_DESC sd,
745 void *data)
746{
747 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
748 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
749}
750
751
752/* Generic resume - assumes the existance of sim_engine_run */
753
754void
755sim_resume (SIM_DESC sd,
756 int step,
757 int siggnal)
758{
759 sim_engine *engine = STATE_ENGINE (sd);
760 jmp_buf buf;
761 int jmpval;
762
763 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
764
765 /* we only want to be single stepping the simulator once */
766 if (engine->stepper != NULL)
767 {
768 sim_events_deschedule (sd, engine->stepper);
769 engine->stepper = NULL;
770 }
771 sim_module_resume (sd);
772
773 /* run/resume the simulator */
774 engine->jmpbuf = &buf;
775 jmpval = setjmp (buf);
776 if (jmpval == sim_engine_start_jmpval
777 || jmpval == sim_engine_restart_jmpval)
778 {
779 int last_cpu_nr = sim_engine_last_cpu_nr (sd);
780 int next_cpu_nr = sim_engine_next_cpu_nr (sd);
781 int nr_cpus = sim_engine_nr_cpus (sd);
782
783 sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
784 if (next_cpu_nr >= nr_cpus)
785 next_cpu_nr = 0;
786
787 /* Only deliver the siggnal ]sic] the first time through - don't
788 re-deliver any siggnal during a restart. */
789 if (jmpval == sim_engine_restart_jmpval)
790 siggnal = 0;
791
792 /* Install the stepping event after having processed some
793 pending events. This is necessary for HC11/HC12 simulator
794 because the tick counter is incremented by the number of cycles
795 the instruction took. Some pending ticks to process can still
796 be recorded internally by the simulator and sim_events_preprocess
797 will handle them. If the stepping event is inserted before,
798 these pending ticks will raise the event and the simulator will
799 stop without having executed any instruction. */
800 if (step)
801 engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
802
803#ifdef SIM_CPU_EXCEPTION_RESUME
804 {
805 sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
806 SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
807 }
808#endif
809
810 sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
811 }
812 engine->jmpbuf = NULL;
813
814 sim_module_suspend (sd);
815}