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