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