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)
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)
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.
#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;
// 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__ */