+sim_set_interrupt (spec)
+ char *spec;
+{
+ int i, num;
+ char **argv;
+ struct interrupt_generator *intgen, *tmpgen;
+ extern char **buildargv ();
+
+ argv = buildargv (spec);
+
+ if (*argv && ! strcmp (*argv, "add"))
+ {
+ /* Create a new interrupt generator object. */
+ intgen = (struct interrupt_generator *)
+ malloc (sizeof(struct interrupt_generator));
+ intgen->type = int_none;
+ intgen->cond_type = int_cond_none;
+ intgen->address = 0;
+ intgen->time = 0;
+ intgen->enabled = 0;
+ ++argv;
+ /* Match on interrupt type name. */
+ for (i = 0; i < num_int_types; ++i)
+ {
+ if (*argv && ! strcmp (*argv, interrupt_names[i]))
+ {
+ intgen->type = i;
+ break;
+ }
+ }
+ if (intgen->type == int_none)
+ {
+ (*v850_callback->printf_filtered) (v850_callback, "Interrupt type unknown; known types are\n");
+ for (i = 0; i < num_int_types; ++i)
+ {
+ (*v850_callback->printf_filtered) (v850_callback, " %s", interrupt_names[i]);
+ }
+ (*v850_callback->printf_filtered) (v850_callback, "\n");
+ free (intgen);
+ return;
+ }
+ ++argv;
+ intgen->address = 0;
+ intgen->time = 0;
+ if (*argv && ! strcmp (*argv, "pc"))
+ {
+ intgen->cond_type = int_cond_pc;
+ ++argv;
+ intgen->address = sim_parse_number (*argv, NULL);
+ }
+ else if (*argv && ! strcmp (*argv, "time"))
+ {
+ intgen->cond_type = int_cond_time;
+ ++argv;
+ intgen->time = sim_parse_number (*argv, NULL);
+ }
+ else
+ {
+ (*v850_callback->printf_filtered) (v850_callback, "Condition type must be `pc' or `time'.\n");
+ free (intgen);
+ return;
+ }
+ /* We now have a valid interrupt generator. Number it and add
+ to the list of generators. */
+ intgen->number = current_intgen_number++;
+ intgen->enabled = 1;
+ intgen->next = intgen_list;
+ intgen_list = intgen;
+ (*v850_callback->printf_filtered) (v850_callback, "Interrupt generator %d (NMI) at pc=0x%x, time=%d.\n", intgen_list->number, intgen_list->address, intgen_list->time);
+ }
+ else if (*argv && !strcmp (*argv, "remove"))
+ {
+ ++argv;
+ num = sim_parse_number (*argv, NULL);
+ tmpgen = NULL;
+ if (intgen_list)
+ {
+ if (intgen_list->number == num)
+ {
+ tmpgen = intgen_list;
+ intgen_list = intgen_list->next;
+ }
+ else
+ {
+ for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
+ {
+ if (intgen->next != NULL && intgen->next->number == num)
+ {
+ tmpgen = intgen->next;
+ intgen->next = intgen->next->next;
+ break;
+ }
+ }
+ }
+ if (tmpgen)
+ free (tmpgen);
+ else
+ (*v850_callback->printf_filtered) (v850_callback,
+ "No interrupt generator numbered %d, ignoring.\n", num);
+ }
+ }
+ else if (*argv && !strcmp (*argv, "info"))
+ {
+ if (intgen_list)
+ {
+ for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
+ (*v850_callback->printf_filtered) (v850_callback,
+ "Interrupt generator %d (%s) at pc=0x%x/time=%d%s.\n",
+ intgen->number,
+ interrupt_names[intgen->type],
+ intgen->address,
+ intgen->time,
+ (intgen->enabled ? "" : " (disabled)"));
+ }
+ else
+ {
+ (*v850_callback->printf_filtered) (v850_callback, "No interrupt generators defined.\n");
+ }
+
+ }
+ else
+ {
+ (*v850_callback->printf_filtered) (v850_callback,
+ "Invalid interrupt command, must be one of `add', `remove', or `info'.\n");
+ }
+ /* Cache the presence of a non-maskable generator. */
+ have_nm_generator = 0;
+ for (intgen = intgen_list; intgen != NULL; intgen = intgen->next)
+ {
+ if (intgen->type == int_nmi || intgen->type == int_reset)
+ {
+ have_nm_generator = 1;
+ break;
+ }
+ }
+}
+
+void
+sim_do_command (sd, cmd)
+ SIM_DESC sd;