#include <hlib.h> #include <stdbool.h> #include <stdint.h> #define PIC1 0x20 #define PIC2 0xA0 char *eventNames[] = { "irq0", "irq1", "irq2", "irq3", "irq4", "irq5", "irq6", "irq7", "irq8", "irq9", "irq10", "irq11", "irq12", "irq13", "irq14", "irq15", }; uint32_t eventIds[16]; #define PIC_READ_IRR 0x0A uint16_t getIRR() { ioOut(PIC1, PIC_READ_IRR, 1); ioOut(PIC2, PIC_READ_IRR, 1); return (ioIn(PIC2, 1) << 8) | ioIn(PIC1, 1); } #define PIC_READ_ISR 0x0B uint16_t getISR() { ioOut(PIC1, PIC_READ_ISR, 1); uint16_t first = ioIn(PIC1, 1); ioOut(PIC2, PIC_READ_ISR, 1); uint16_t second = ioIn(PIC2, 1) << 8; return first | second; } void irqMaster(uint32_t intNo) { uint16_t isr = getISR(); bool sendPic2EOI = false; for (uint8_t i = 0; i < 16; i++) { if (!(isr & (1 << i))) { continue; } if (i >= 8) { sendPic2EOI = true; } fireEvent(eventIds[i], i); } if (isr) { ioOut(PIC1, 0x20, 1); if (sendPic2EOI) { ioOut(PIC2, 0x20, 1); } } } int32_t main() { printf("setting up interrupt handlers for the PIC\n"); for (uint32_t i = 32; i < 48; i++) { subscribeInterrupt(i, irqMaster); } ioOut(0x21, 0x0, 1); ioOut(0xA1, 0x0, 1); ioOut(0x70, ioIn(0x70, 1) | 0x80, 1); ioIn(0x71, 1); for (uint8_t i = 0; i < sizeof(eventNames) / sizeof(uintptr_t); i++) { eventIds[i] = createEvent(eventNames[i]); } }