interrupts: Added a "raised" IRQ
authorMichel Pollet <buserror@gmail.com>
Thu, 17 Dec 2009 20:22:10 +0000 (20:22 +0000)
committerMichel Pollet <buserror@gmail.com>
Thu, 17 Dec 2009 20:22:10 +0000 (20:22 +0000)
Added a "raise" IRQ that is set to 1 when the interrupt is
scheduled, and to 0 when the handler is called.
This allows the interrupts to be traced into a VCD file
waveform, amongst other things.

Signed-off-by: Michel Pollet <buserror@gmail.com>
simavr/sim/sim_interrupts.c
simavr/sim/sim_interrupts.h

index 41e2f40..bd600e6 100644 (file)
 
 void avr_register_vector(avr_t *avr, avr_int_vector_t * vector)
 {
-       if (vector->vector)
+       if (vector->vector) {
+               vector->irq.irq = vector->vector;
                avr->vector[vector->vector] = vector;
+       }
 }
 
 int avr_has_pending_interrupts(avr_t * avr)
@@ -61,6 +63,7 @@ int avr_raise_interrupt(avr_t * avr, avr_int_vector_t * vector)
                if (!avr->pending_wait)
                        avr->pending_wait = 2;          // latency on interrupts ??
                avr->pending[vector->vector >> 5] |= (1 << (vector->vector & 0x1f));
+               avr_raise_irq(&vector->irq, 1);
 
                if (avr->state != cpu_Running) {
                        if (vector->trace)
@@ -80,10 +83,17 @@ void avr_clear_interrupt(avr_t * avr, int v)
                return;
        if (vector->trace)
                printf("%s cleared %d\n", __FUNCTION__, vector->vector);
+       avr_raise_irq(&vector->irq, 0);
        if (vector->raised.reg)
                avr_regbit_clear(avr, vector->raised);
 }
 
+avr_irq_t * avr_get_interupt_irq(avr_t * avr, uint8_t v)
+{
+       avr_int_vector_t * vector = avr->vector[v];
+       return vector ? &vector->irq : NULL;
+}
+
 /*
  * check wether interrupts are pending. I so, check if the interrupt "latency" is reached,
  * and if so triggers the handlers and jump to the vector.
index 26017cb..71f308e 100644 (file)
 #define __SIM_INTERUPTS_H__
 
 #include "sim_avr.h"
+#include "sim_irq.h"
 
 // interrupt vector for the IO modules
 typedef struct avr_int_vector_t {
-       uint8_t vector;         // vector number, zero (reset) is reserved
-
+       uint8_t vector;                 // vector number, zero (reset) is reserved
        avr_regbit_t enable;    // IO register index for the "interrupt enable" flag for this vector
        avr_regbit_t raised;    // IO register index for the register where the "raised" flag is (optional)
 
+       avr_irq_t               irq;            // raised to 1 when queued, to zero when called
        uint8_t                 trace;          // only for debug of a vector
 } avr_int_vector_t;
 
@@ -52,4 +53,8 @@ void avr_clear_interrupt(avr_t * avr, int v);
 // called by the core at each cycle to check whether an interrupt is pending
 void avr_service_interrupts(avr_t * avr);
 
+// return the IRQ that is raised when the vector is enabled and called/cleared
+// this allows tracing of pending interupts
+avr_irq_t * avr_get_interupt_irq(avr_t * avr, uint8_t v);
+
 #endif /* __SIM_INTERUPTS_H__ */