diff options
author | H. Peter Anvin <hpa@zytor.com> | 2018-10-29 23:34:26 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2018-10-29 23:34:26 -0700 |
commit | 64e32a88a18c3ff6790578a62249b40411c829d9 (patch) | |
tree | d1cb6f6f70650ad39d2f454ef4912d7433cb8067 | |
parent | 667f4f71e8a875e199ab61ed15d4da45d8402249 (diff) | |
download | abc80sim-64e32a88a18c3ff6790578a62249b40411c829d9.tar.gz abc80sim-64e32a88a18c3ff6790578a62249b40411c829d9.tar.xz abc80sim-64e32a88a18c3ff6790578a62249b40411c829d9.zip |
irq: change the IRQ interface to use struct z80_irq consistently
It is better than to futz with numeric priority levels, even though it
otherwise would be theoretically possible to use a shared z80_irq
structure for more than one interrupt: it is simply not worth it.
Using struct z80_irq * consistently makes for a more flexible API in
the future.
-rw-r--r-- | abcio.c | 8 | ||||
-rw-r--r-- | cas.c | 16 | ||||
-rw-r--r-- | clock.c | 2 | ||||
-rw-r--r-- | z80irq.c | 32 | ||||
-rw-r--r-- | z80irq.h | 8 |
5 files changed, 27 insertions, 39 deletions
@@ -21,7 +21,7 @@ static uint8_t keyb_fakedata; /* Fake minimal-touch input */ bool faketype; -static int keyb_intack_fake(unsigned int prio, struct z80_irq *irq); +static int keyb_intack_fake(struct z80_irq *irq); static struct z80_irq *keyb_irq; static struct z80_irq keyb_irq_80 = @@ -186,12 +186,10 @@ static unsigned int get_key(void) return rv; } -static int keyb_intack_fake(unsigned int prio, struct z80_irq *irq) +static int keyb_intack_fake(struct z80_irq *irq) { unsigned int data = get_key(); - (void)prio; - keyb_fakedata = (data & 0x7f) | ((data & KEYB_NEW) ? 0x80 : 0x00); return irq->vector; @@ -454,7 +452,7 @@ void keyboard_down(int sym) } keyb_data = sym | KEYB_NEW | KEYB_DOWN; - z80_interrupt(keyb_irq->prio); + z80_interrupt(keyb_irq); } unsigned int keyboard_up(void) @@ -170,7 +170,7 @@ static bool cas_edge(void) /* * ABC80 PIO interfacing */ -static inline int pio_eoi(unsigned int, struct z80_irq *); +static inline int pio_eoi(struct z80_irq *); enum pioctl_state { pcs_init, @@ -213,14 +213,13 @@ static void pio_check_interrupt(struct pio *pio) (pio->irqctl & 0x40) ? (masked == pio->irqmask) : (masked != 0); if (trigger) - z80_interrupt(pio->irq.prio); + z80_interrupt(&pio->irq); else - z80_clear_interrupt(pio->irq.prio); + z80_clear_interrupt(&pio->irq); } -static int pio_eoi(unsigned int prio, struct z80_irq *irq) +static int pio_eoi(struct z80_irq *irq) { - (void)prio; pio_check_interrupt((struct pio *)(irq->pvt)); return 0; } @@ -329,7 +328,7 @@ void abc80_cas_init(void) * - At end of block either hardware or software go back to need sync */ -static int sio_cas_eoi(unsigned int prio, struct z80_irq *irq); +static int sio_cas_eoi(struct z80_irq *irq); static uint8_t sio_cas_ctl[8]; static bool cas_first_rx_armed = true; @@ -354,9 +353,8 @@ static inline bool cas_rx_interrupt(bool huntok) static void cas_poll_interrupt(void); -static int sio_cas_eoi(unsigned int prio, struct z80_irq *irq) +static int sio_cas_eoi(struct z80_irq *irq) { - (void)prio; (void)irq; cas_poll_interrupt(); @@ -372,7 +370,7 @@ static void cas_poll_interrupt(void) sio_cas_ctl[3] &= ~0x10; /* Not hunting anymore */ cas_first_rx_armed = false; sio_cas_irq.vector = (sio_cas_ctl[2] & ~0x0f) | 0x04; - z80_interrupt(sio_cas_irq.prio); + z80_interrupt(&sio_cas_irq); } void abc800_sio_cas_out(uint8_t port, uint8_t v) @@ -197,7 +197,7 @@ static struct z80_irq ctc_irq[4] = static void abc800_clock_tick(void) { if ((ctc_ctl[3] & 0xc0) == 0x80) - z80_interrupt(IRQ800_CTC3); + z80_interrupt(&ctc_irq[3]); } /* @@ -5,7 +5,6 @@ volatile unsigned int irq_pending; /* Quick way to poll */ static struct z80_irq *irqs[MAX_IRQ]; static struct z80_irq *current_irq; -static unsigned int current_prio; void z80_register_irq(struct z80_irq *irq) { @@ -36,13 +35,12 @@ int z80_intack(void) irq = irqs[prio]; if (unlikely(irq->intack)) - vector = irq->intack(prio, irq); + vector = irq->intack(irq); else vector = irq->vector; } while (vector < 0); current_irq = irq; - current_prio = prio; return vector; } @@ -58,10 +56,10 @@ void z80_eoi(void) if (!irq) return; /* No known interrupt to EOI */ - if (irq->eoi) - irq->eoi(current_prio, irq); - current_irq = NULL; + + if (irq->eoi) + irq->eoi(irq); } /* @@ -71,38 +69,35 @@ void z80_eoi(void) */ #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -bool z80_interrupt(unsigned int prio) +bool z80_interrupt(struct z80_irq *irq) { bool raised; asm volatile("lock btsl %2,%0" : "+m" (irq_pending), "=@ccnc" (raised) - : "ri" (prio)); + : "rN" (irq->prio)); return raised; } -bool z80_clear_interrupt(unsigned int prio) +bool z80_clear_interrupt(struct z80_irq *irq) { bool cleared; asm volatile("lock btrl %2,%0" : "+m" (irq_pending), "=@ccc" (cleared) - : "ri" (prio)); + : "rN" (irq->prio)); return cleared; } #else -bool z80_interrupt(unsigned int prio) +bool z80_interrupt(struct z80_irq *irq) { unsigned int irqmask, irqpend; - if (prio >= MAX_IRQ) - return false; - - irqmask = 1U << prio; + irqmask = 1U << irq->prio; irqpend = irq_pending; do { if (irqpend & irqmask) @@ -112,14 +107,11 @@ bool z80_interrupt(unsigned int prio) return true; } -bool z80_clear_interrupt(unsigned int prio) +bool z80_clear_interrupt(struct z80_irq *irq) { unsigned int irqmask, irqpend; - if (prio >= MAX_IRQ) - return false; - - irqmask = 1U << prio; + irqmask = 1U << irq->prio; irqpend = irq_pending; do { if (!(irqpend & irqmask)) @@ -4,14 +4,14 @@ #include "compiler.h" #include "z80.h" -typedef int (*irq_func)(unsigned int prio, struct z80_irq *irq); +typedef int (*irq_func)(struct z80_irq *irq); struct z80_irq { irq_func intack; irq_func eoi; void *pvt; /* Available for user */ int vector; /* Available for user if intack defined */ - unsigned int prio; /* Available for user after register_irq */ + unsigned int prio; /* Priority level */ }; #define MAX_IRQ 32 @@ -25,7 +25,7 @@ static inline bool poll_irq(void) void z80_register_irq(struct z80_irq *irq); int z80_intack(void); void z80_eoi(void); -bool z80_interrupt(unsigned int prio); -bool z80_clear_interrupt(unsigned int prio); +bool z80_interrupt(struct z80_irq *irq); +bool z80_clear_interrupt(struct z80_irq *irq); #endif /* Z80IRQ_H */ |