]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/m68hc11/interrupts.c
sim: split sim-signal.h include out
[thirdparty/binutils-gdb.git] / sim / m68hc11 / interrupts.c
CommitLineData
e0709f50 1/* interrupts.c -- 68HC11 Interrupts Emulation
3666a048 2 Copyright 1999-2021 Free Software Foundation, Inc.
a685700c 3 Written by Stephane Carrez (stcarrez@nerim.fr)
e0709f50
AC
4
5This file is part of GDB, GAS, and the GNU binutils.
6
4744ac1b
JB
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
e0709f50 11
4744ac1b
JB
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
e0709f50
AC
16
17You should have received a copy of the GNU General Public License
4744ac1b 18along with this program. If not, see <http://www.gnu.org/licenses/>. */
e0709f50 19
6df01ab8
MF
20/* This must come before any other includes. */
21#include "defs.h"
22
e0709f50 23#include "sim-main.h"
26128965 24#include "sim-options.h"
1fef66b0 25#include "sim-signal.h"
26128965
SC
26
27static const char *interrupt_names[] = {
28 "R1",
29 "R2",
30 "R3",
31 "R4",
32 "R5",
33 "R6",
34 "R7",
35 "R8",
36 "R9",
37 "R10",
38 "R11",
39
40 "SCI",
41 "SPI",
42 "AINPUT",
43 "AOVERFLOW",
44 "TOVERFLOW",
45 "OUT5",
46 "OUT4",
47 "OUT3",
48 "OUT2",
49 "OUT1",
50 "INC3",
51 "INC2",
52 "INC1",
53 "RT",
54 "IRQ",
55 "XIRQ",
56 "SWI",
57 "ILL",
58 "COPRESET",
59 "COPFAIL",
60 "RESET"
61};
e0709f50
AC
62
63struct interrupt_def idefs[] = {
64 /* Serial interrupts. */
65 { M6811_INT_SCI, M6811_SCSR, M6811_TDRE, M6811_SCCR2, M6811_TIE },
66 { M6811_INT_SCI, M6811_SCSR, M6811_TC, M6811_SCCR2, M6811_TCIE },
67 { M6811_INT_SCI, M6811_SCSR, M6811_RDRF, M6811_SCCR2, M6811_RIE },
68 { M6811_INT_SCI, M6811_SCSR, M6811_IDLE, M6811_SCCR2, M6811_ILIE },
69
70 /* SPI interrupts. */
71 { M6811_INT_SPI, M6811_SPSR, M6811_SPIF, M6811_SPCR, M6811_SPIE },
72
73 /* Realtime interrupts. */
74 { M6811_INT_TCTN, M6811_TFLG2, M6811_TOF, M6811_TMSK2, M6811_TOI },
75 { M6811_INT_RT, M6811_TFLG2, M6811_RTIF, M6811_TMSK2, M6811_RTII },
76
77 /* Output compare interrupts. */
78 { M6811_INT_OUTCMP1, M6811_TFLG1, M6811_OC1F, M6811_TMSK1, M6811_OC1I },
79 { M6811_INT_OUTCMP2, M6811_TFLG1, M6811_OC2F, M6811_TMSK1, M6811_OC2I },
80 { M6811_INT_OUTCMP3, M6811_TFLG1, M6811_OC3F, M6811_TMSK1, M6811_OC3I },
81 { M6811_INT_OUTCMP4, M6811_TFLG1, M6811_OC4F, M6811_TMSK1, M6811_OC4I },
82 { M6811_INT_OUTCMP5, M6811_TFLG1, M6811_OC5F, M6811_TMSK1, M6811_OC5I },
83
84 /* Input compare interrupts. */
85 { M6811_INT_INCMP1, M6811_TFLG1, M6811_IC1F, M6811_TMSK1, M6811_IC1I },
86 { M6811_INT_INCMP2, M6811_TFLG1, M6811_IC2F, M6811_TMSK1, M6811_IC2I },
87 { M6811_INT_INCMP3, M6811_TFLG1, M6811_IC3F, M6811_TMSK1, M6811_IC3I },
26128965
SC
88
89 /* Pulse accumulator. */
90 { M6811_INT_AINPUT, M6811_TFLG2, M6811_PAIF, M6811_TMSK2, M6811_PAII },
91 { M6811_INT_AOVERFLOW,M6811_TFLG2, M6811_PAOVF, M6811_TMSK2, M6811_PAOVI},
e0709f50
AC
92#if 0
93 { M6811_INT_COPRESET, M6811_CONFIG, M6811_NOCOP, 0, 0 },
94 { M6811_INT_COPFAIL, M6811_CONFIG, M6811_NOCOP, 0, 0 }
95#endif
96};
97
e0709f50
AC
98#define CYCLES_MAX ((((signed64) 1) << 62) - 1)
99
26128965
SC
100enum
101{
102 OPTION_INTERRUPT_INFO = OPTION_START,
103 OPTION_INTERRUPT_CATCH,
104 OPTION_INTERRUPT_CLEAR
105};
106
107static DECLARE_OPTION_HANDLER (interrupt_option_handler);
108
109static const OPTION interrupt_options[] =
110{
111 { {"interrupt-info", no_argument, NULL, OPTION_INTERRUPT_INFO },
112 '\0', NULL, "Print information about interrupts",
113 interrupt_option_handler },
114 { {"interrupt-catch", required_argument, NULL, OPTION_INTERRUPT_CATCH },
115 '\0', "NAME[,MODE]",
116 "Catch interrupts when they are raised or taken\n"
117 "NAME Name of the interrupt\n"
118 "MODE Optional mode (`taken' or `raised')",
119 interrupt_option_handler },
120 { {"interrupt-clear", required_argument, NULL, OPTION_INTERRUPT_CLEAR },
121 '\0', "NAME", "No longer catch the interrupt",
122 interrupt_option_handler },
123
124 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
125};
126
127/* Initialize the interrupts module. */
128void
6f64fd48 129interrupts_initialize (SIM_DESC sd, sim_cpu *cpu)
e0709f50 130{
6f64fd48 131 struct interrupts *interrupts = &cpu->cpu_interrupts;
e0709f50 132
6f64fd48 133 interrupts->cpu = cpu;
26128965
SC
134
135 sim_add_option_table (sd, 0, interrupt_options);
136}
137
138/* Initialize the interrupts of the processor. */
139void
140interrupts_reset (struct interrupts *interrupts)
141{
142 int i;
143
e0709f50 144 interrupts->pending_mask = 0;
26128965
SC
145 if (interrupts->cpu->cpu_mode & M6811_SMOD)
146 interrupts->vectors_addr = 0xbfc0;
147 else
148 interrupts->vectors_addr = 0xffc0;
e0709f50
AC
149 interrupts->nb_interrupts_raised = 0;
150 interrupts->min_mask_cycles = CYCLES_MAX;
151 interrupts->max_mask_cycles = 0;
11115521 152 interrupts->last_mask_cycles = 0;
e0709f50
AC
153 interrupts->start_mask_cycle = -1;
154 interrupts->xirq_start_mask_cycle = -1;
155 interrupts->xirq_max_mask_cycles = 0;
156 interrupts->xirq_min_mask_cycles = CYCLES_MAX;
11115521 157 interrupts->xirq_last_mask_cycles = 0;
e0709f50
AC
158
159 for (i = 0; i < M6811_INT_NUMBER; i++)
160 {
161 interrupts->interrupt_order[i] = i;
162 }
26128965
SC
163
164 /* Clear the interrupt history table. */
165 interrupts->history_index = 0;
166 memset (interrupts->interrupts_history, 0,
167 sizeof (interrupts->interrupts_history));
168
169 memset (interrupts->interrupts, 0,
170 sizeof (interrupts->interrupts));
a685700c
SC
171
172 /* In bootstrap mode, initialize the vector table to point
173 to the RAM location. */
174 if (interrupts->cpu->cpu_mode == M6811_SMOD)
175 {
176 bfd_vma addr = interrupts->vectors_addr;
177 uint16 vector = 0x0100 - 3 * (M6811_INT_NUMBER - 1);
178 for (i = 0; i < M6811_INT_NUMBER; i++)
179 {
180 memory_write16 (interrupts->cpu, addr, vector);
181 addr += 2;
182 vector += 3;
183 }
184 }
26128965
SC
185}
186
187static int
188find_interrupt (const char *name)
189{
190 int i;
191
192 if (name)
193 for (i = 0; i < M6811_INT_NUMBER; i++)
194 if (strcasecmp (name, interrupt_names[i]) == 0)
195 return i;
196
197 return -1;
e0709f50
AC
198}
199
26128965
SC
200static SIM_RC
201interrupt_option_handler (SIM_DESC sd, sim_cpu *cpu,
202 int opt, char *arg, int is_command)
203{
204 char *p;
205 int mode;
206 int id;
207 struct interrupts *interrupts;
208
209 if (cpu == 0)
210 cpu = STATE_CPU (sd, 0);
211
212 interrupts = &cpu->cpu_interrupts;
213 switch (opt)
214 {
215 case OPTION_INTERRUPT_INFO:
216 for (id = 0; id < M6811_INT_NUMBER; id++)
217 {
218 sim_io_eprintf (sd, "%-10.10s ", interrupt_names[id]);
219 switch (interrupts->interrupts[id].stop_mode)
220 {
221 case SIM_STOP_WHEN_RAISED:
222 sim_io_eprintf (sd, "catch raised ");
223 break;
224
225 case SIM_STOP_WHEN_TAKEN:
226 sim_io_eprintf (sd, "catch taken ");
227 break;
228
229 case SIM_STOP_WHEN_RAISED | SIM_STOP_WHEN_TAKEN:
230 sim_io_eprintf (sd, "catch all ");
231 break;
232
233 default:
234 sim_io_eprintf (sd, " ");
235 break;
236 }
237 sim_io_eprintf (sd, "%ld\n",
238 interrupts->interrupts[id].raised_count);
239 }
240 break;
241
242 case OPTION_INTERRUPT_CATCH:
243 p = strchr (arg, ',');
244 if (p)
245 *p++ = 0;
246
247 mode = SIM_STOP_WHEN_RAISED;
248 id = find_interrupt (arg);
249 if (id < 0)
250 sim_io_eprintf (sd, "Interrupt name not recognized: %s\n", arg);
251
252 if (p && strcasecmp (p, "raised") == 0)
253 mode = SIM_STOP_WHEN_RAISED;
254 else if (p && strcasecmp (p, "taken") == 0)
255 mode = SIM_STOP_WHEN_TAKEN;
256 else if (p && strcasecmp (p, "all") == 0)
257 mode = SIM_STOP_WHEN_RAISED | SIM_STOP_WHEN_TAKEN;
258 else if (p)
259 {
260 sim_io_eprintf (sd, "Invalid argument: %s\n", p);
261 break;
262 }
263 if (id >= 0)
264 interrupts->interrupts[id].stop_mode = mode;
265 break;
266
267 case OPTION_INTERRUPT_CLEAR:
268 mode = SIM_STOP_WHEN_RAISED;
269 id = find_interrupt (arg);
270 if (id < 0)
271 sim_io_eprintf (sd, "Interrupt name not recognized: %s\n", arg);
272 else
273 interrupts->interrupts[id].stop_mode = 0;
274 break;
275 }
276
277 return SIM_RC_OK;
278}
e0709f50
AC
279
280/* Update the mask of pending interrupts. This operation must be called
26128965 281 when the state of some 68HC11 IO register changes. It looks the
e0709f50
AC
282 different registers that indicate a pending interrupt (timer, SCI, SPI,
283 ...) and records the interrupt if it's there and enabled. */
284void
285interrupts_update_pending (struct interrupts *interrupts)
286{
287 int i;
288 uint8 *ioregs;
11115521
SC
289 unsigned long clear_mask;
290 unsigned long set_mask;
e0709f50 291
11115521
SC
292 clear_mask = 0;
293 set_mask = 0;
e0709f50
AC
294 ioregs = &interrupts->cpu->ios[0];
295
13a590ca 296 for (i = 0; i < ARRAY_SIZE (idefs); i++)
e0709f50
AC
297 {
298 struct interrupt_def *idef = &idefs[i];
299 uint8 data;
300
301 /* Look if the interrupt is enabled. */
302 if (idef->enable_paddr)
303 {
304 data = ioregs[idef->enable_paddr];
305 if (!(data & idef->enabled_mask))
a8afa79a
SC
306 {
307 /* Disable it. */
11115521 308 clear_mask |= (1 << idef->int_number);
a8afa79a
SC
309 continue;
310 }
e0709f50
AC
311 }
312
313 /* Interrupt is enabled, see if it's there. */
314 data = ioregs[idef->int_paddr];
315 if (!(data & idef->int_mask))
a8afa79a
SC
316 {
317 /* Disable it. */
11115521 318 clear_mask |= (1 << idef->int_number);
a8afa79a
SC
319 continue;
320 }
e0709f50
AC
321
322 /* Ok, raise it. */
11115521 323 set_mask |= (1 << idef->int_number);
e0709f50 324 }
11115521
SC
325
326 /* Some interrupts are shared (M6811_INT_SCI) so clear
327 the interrupts before setting the new ones. */
328 interrupts->pending_mask &= ~clear_mask;
329 interrupts->pending_mask |= set_mask;
26128965
SC
330
331 /* Keep track of when the interrupt is raised by the device.
332 Also implements the breakpoint-on-interrupt. */
333 if (set_mask)
334 {
335 signed64 cycle = cpu_current_cycle (interrupts->cpu);
336 int must_stop = 0;
337
338 for (i = 0; i < M6811_INT_NUMBER; i++)
339 {
340 if (!(set_mask & (1 << i)))
341 continue;
342
343 interrupts->interrupts[i].cpu_cycle = cycle;
344 if (interrupts->interrupts[i].stop_mode & SIM_STOP_WHEN_RAISED)
345 {
346 must_stop = 1;
347 sim_io_printf (CPU_STATE (interrupts->cpu),
348 "Interrupt %s raised\n",
349 interrupt_names[i]);
350 }
351 }
352 if (must_stop)
353 sim_engine_halt (CPU_STATE (interrupts->cpu),
354 interrupts->cpu,
355 0, cpu_get_pc (interrupts->cpu),
356 sim_stopped,
357 SIM_SIGTRAP);
358 }
e0709f50
AC
359}
360
361
362/* Finds the current active and non-masked interrupt.
363 Returns the interrupt number (index in the vector table) or -1
364 if no interrupt can be serviced. */
365int
366interrupts_get_current (struct interrupts *interrupts)
367{
368 int i;
369
370 if (interrupts->pending_mask == 0)
371 return -1;
372
373 /* SWI and illegal instructions are simulated by an interrupt.
374 They are not maskable. */
375 if (interrupts->pending_mask & (1 << M6811_INT_SWI))
376 {
377 interrupts->pending_mask &= ~(1 << M6811_INT_SWI);
378 return M6811_INT_SWI;
379 }
380 if (interrupts->pending_mask & (1 << M6811_INT_ILLEGAL))
381 {
382 interrupts->pending_mask &= ~(1 << M6811_INT_ILLEGAL);
383 return M6811_INT_ILLEGAL;
384 }
385
386 /* If there is a non maskable interrupt, go for it (unless we are masked
387 by the X-bit. */
388 if (interrupts->pending_mask & (1 << M6811_INT_XIRQ))
389 {
390 if (cpu_get_ccr_X (interrupts->cpu) == 0)
391 {
392 interrupts->pending_mask &= ~(1 << M6811_INT_XIRQ);
393 return M6811_INT_XIRQ;
394 }
395 return -1;
396 }
397
398 /* Interrupts are masked, do nothing. */
399 if (cpu_get_ccr_I (interrupts->cpu) == 1)
400 {
401 return -1;
402 }
403
404 /* Returns the first interrupt number which is pending.
a8afa79a
SC
405 The interrupt priority is specified by the table `interrupt_order'.
406 For these interrupts, the pending mask is cleared when the program
407 performs some actions on the corresponding device. If the device
408 is not reset, the interrupt remains and will be re-raised when
409 we return from the interrupt (see 68HC11 pink book). */
e0709f50
AC
410 for (i = 0; i < M6811_INT_NUMBER; i++)
411 {
412 enum M6811_INT int_number = interrupts->interrupt_order[i];
413
414 if (interrupts->pending_mask & (1 << int_number))
415 {
e0709f50
AC
416 return int_number;
417 }
418 }
419 return -1;
420}
421
422
423/* Process the current interrupt if there is one. This operation must
424 be called after each instruction to handle the interrupts. If interrupts
425 are masked, it does nothing. */
426int
427interrupts_process (struct interrupts *interrupts)
428{
429 int id;
430 uint8 ccr;
431
432 /* See if interrupts are enabled/disabled and keep track of the
433 number of cycles the interrupts are masked. Such information is
434 then reported by the info command. */
435 ccr = cpu_get_ccr (interrupts->cpu);
436 if (ccr & M6811_I_BIT)
437 {
438 if (interrupts->start_mask_cycle < 0)
439 interrupts->start_mask_cycle = cpu_current_cycle (interrupts->cpu);
440 }
441 else if (interrupts->start_mask_cycle >= 0
442 && (ccr & M6811_I_BIT) == 0)
443 {
444 signed64 t = cpu_current_cycle (interrupts->cpu);
445
446 t -= interrupts->start_mask_cycle;
447 if (t < interrupts->min_mask_cycles)
448 interrupts->min_mask_cycles = t;
449 if (t > interrupts->max_mask_cycles)
450 interrupts->max_mask_cycles = t;
451 interrupts->start_mask_cycle = -1;
11115521 452 interrupts->last_mask_cycles = t;
e0709f50
AC
453 }
454 if (ccr & M6811_X_BIT)
455 {
456 if (interrupts->xirq_start_mask_cycle < 0)
457 interrupts->xirq_start_mask_cycle
458 = cpu_current_cycle (interrupts->cpu);
459 }
460 else if (interrupts->xirq_start_mask_cycle >= 0
461 && (ccr & M6811_X_BIT) == 0)
462 {
463 signed64 t = cpu_current_cycle (interrupts->cpu);
464
465 t -= interrupts->xirq_start_mask_cycle;
466 if (t < interrupts->xirq_min_mask_cycles)
467 interrupts->xirq_min_mask_cycles = t;
468 if (t > interrupts->xirq_max_mask_cycles)
469 interrupts->xirq_max_mask_cycles = t;
470 interrupts->xirq_start_mask_cycle = -1;
11115521 471 interrupts->xirq_last_mask_cycles = t;
e0709f50
AC
472 }
473
474 id = interrupts_get_current (interrupts);
475 if (id >= 0)
476 {
477 uint16 addr;
26128965
SC
478 struct interrupt_history *h;
479
480 /* Implement the breakpoint-on-interrupt. */
481 if (interrupts->interrupts[id].stop_mode & SIM_STOP_WHEN_TAKEN)
482 {
483 sim_io_printf (CPU_STATE (interrupts->cpu),
484 "Interrupt %s will be handled\n",
485 interrupt_names[id]);
486 sim_engine_halt (CPU_STATE (interrupts->cpu),
487 interrupts->cpu,
488 0, cpu_get_pc (interrupts->cpu),
489 sim_stopped,
490 SIM_SIGTRAP);
491 }
492
e0709f50
AC
493 cpu_push_all (interrupts->cpu);
494 addr = memory_read16 (interrupts->cpu,
495 interrupts->vectors_addr + id * 2);
496 cpu_call (interrupts->cpu, addr);
497
498 /* Now, protect from nested interrupts. */
499 if (id == M6811_INT_XIRQ)
500 {
501 cpu_set_ccr_X (interrupts->cpu, 1);
502 }
503 else
504 {
505 cpu_set_ccr_I (interrupts->cpu, 1);
506 }
507
26128965
SC
508 /* Update the interrupt history table. */
509 h = &interrupts->interrupts_history[interrupts->history_index];
510 h->type = id;
511 h->taken_cycle = cpu_current_cycle (interrupts->cpu);
512 h->raised_cycle = interrupts->interrupts[id].cpu_cycle;
513
514 if (interrupts->history_index >= MAX_INT_HISTORY-1)
515 interrupts->history_index = 0;
516 else
517 interrupts->history_index++;
518
e0709f50
AC
519 interrupts->nb_interrupts_raised++;
520 cpu_add_cycles (interrupts->cpu, 14);
521 return 1;
522 }
523 return 0;
524}
525
526void
527interrupts_raise (struct interrupts *interrupts, enum M6811_INT number)
528{
529 interrupts->pending_mask |= (1 << number);
530 interrupts->nb_interrupts_raised ++;
531}
532
e0709f50
AC
533void
534interrupts_info (SIM_DESC sd, struct interrupts *interrupts)
535{
a685700c 536 signed64 t, prev_interrupt;
26128965 537 int i;
2990a9f4 538
11115521
SC
539 sim_io_printf (sd, "Interrupts Info:\n");
540 sim_io_printf (sd, " Interrupts raised: %lu\n",
541 interrupts->nb_interrupts_raised);
542
e0709f50
AC
543 if (interrupts->start_mask_cycle >= 0)
544 {
2990a9f4 545 t = cpu_current_cycle (interrupts->cpu);
e0709f50
AC
546
547 t -= interrupts->start_mask_cycle;
548 if (t > interrupts->max_mask_cycles)
549 interrupts->max_mask_cycles = t;
e0709f50 550
26128965 551 sim_io_printf (sd, " Current interrupts masked sequence: %s\n",
a685700c
SC
552 cycle_to_string (interrupts->cpu, t,
553 PRINT_TIME | PRINT_CYCLE));
e0709f50 554 }
2990a9f4
SC
555 t = interrupts->min_mask_cycles == CYCLES_MAX ?
556 interrupts->max_mask_cycles :
557 interrupts->min_mask_cycles;
26128965 558 sim_io_printf (sd, " Shortest interrupts masked sequence: %s\n",
a685700c
SC
559 cycle_to_string (interrupts->cpu, t,
560 PRINT_TIME | PRINT_CYCLE));
2990a9f4
SC
561
562 t = interrupts->max_mask_cycles;
26128965 563 sim_io_printf (sd, " Longest interrupts masked sequence: %s\n",
a685700c
SC
564 cycle_to_string (interrupts->cpu, t,
565 PRINT_TIME | PRINT_CYCLE));
2990a9f4 566
11115521 567 t = interrupts->last_mask_cycles;
26128965 568 sim_io_printf (sd, " Last interrupts masked sequence: %s\n",
a685700c
SC
569 cycle_to_string (interrupts->cpu, t,
570 PRINT_TIME | PRINT_CYCLE));
11115521
SC
571
572 if (interrupts->xirq_start_mask_cycle >= 0)
573 {
574 t = cpu_current_cycle (interrupts->cpu);
575
576 t -= interrupts->xirq_start_mask_cycle;
577 if (t > interrupts->xirq_max_mask_cycles)
578 interrupts->xirq_max_mask_cycles = t;
579
580 sim_io_printf (sd, " XIRQ Current interrupts masked sequence: %s\n",
a685700c
SC
581 cycle_to_string (interrupts->cpu, t,
582 PRINT_TIME | PRINT_CYCLE));
11115521
SC
583 }
584
2990a9f4
SC
585 t = interrupts->xirq_min_mask_cycles == CYCLES_MAX ?
586 interrupts->xirq_max_mask_cycles :
587 interrupts->xirq_min_mask_cycles;
26128965 588 sim_io_printf (sd, " XIRQ Min interrupts masked sequence: %s\n",
a685700c
SC
589 cycle_to_string (interrupts->cpu, t,
590 PRINT_TIME | PRINT_CYCLE));
2990a9f4
SC
591
592 t = interrupts->xirq_max_mask_cycles;
26128965 593 sim_io_printf (sd, " XIRQ Max interrupts masked sequence: %s\n",
a685700c
SC
594 cycle_to_string (interrupts->cpu, t,
595 PRINT_TIME | PRINT_CYCLE));
11115521
SC
596
597 t = interrupts->xirq_last_mask_cycles;
598 sim_io_printf (sd, " XIRQ Last interrupts masked sequence: %s\n",
a685700c
SC
599 cycle_to_string (interrupts->cpu, t,
600 PRINT_TIME | PRINT_CYCLE));
26128965
SC
601
602 if (interrupts->pending_mask)
603 {
604 sim_io_printf (sd, " Pending interrupts : ");
605 for (i = 0; i < M6811_INT_NUMBER; i++)
606 {
607 enum M6811_INT int_number = interrupts->interrupt_order[i];
608
609 if (interrupts->pending_mask & (1 << int_number))
610 {
611 sim_io_printf (sd, "%s ", interrupt_names[int_number]);
612 }
613 }
614 sim_io_printf (sd, "\n");
615 }
616
a685700c
SC
617 prev_interrupt = 0;
618 sim_io_printf (sd, "N Interrupt Cycle Taken Latency"
619 " Delta between interrupts\n");
26128965
SC
620 for (i = 0; i < MAX_INT_HISTORY; i++)
621 {
622 int which;
623 struct interrupt_history *h;
624 signed64 dt;
625
626 which = interrupts->history_index - i - 1;
627 if (which < 0)
628 which += MAX_INT_HISTORY;
629 h = &interrupts->interrupts_history[which];
630 if (h->taken_cycle == 0)
631 break;
632
633 dt = h->taken_cycle - h->raised_cycle;
a685700c 634 sim_io_printf (sd, "%2d %-9.9s %15.15s ", i,
26128965 635 interrupt_names[h->type],
a685700c
SC
636 cycle_to_string (interrupts->cpu, h->taken_cycle, 0));
637 sim_io_printf (sd, "%15.15s",
638 cycle_to_string (interrupts->cpu, dt, 0));
639 if (prev_interrupt)
640 {
641 dt = prev_interrupt - h->taken_cycle;
642 sim_io_printf (sd, " %s",
643 cycle_to_string (interrupts->cpu, dt, PRINT_TIME));
644 }
645 sim_io_printf (sd, "\n");
646 prev_interrupt = h->taken_cycle;
26128965 647 }
e0709f50 648}