#include "pic.h" #include "io.h" /* Small delay for older hardware bus timing */ static inline void io_wait(void) { outb(0x80, 0); } void pic_init(void) { uint8_t a1, a2; // Save current masks a1 = inb(PIC1_DATA); a2 = inb(PIC2_DATA); // ICW1: Start initialization in cascade mode outb(PIC1_COMMAND, 0x11); io_wait(); outb(PIC2_COMMAND, 0x11); io_wait(); // ICW2: Master PIC vector offset outb(PIC1_DATA, PIC1_OFFSET); io_wait(); // ICW2: Slave PIC vector offset outb(PIC2_DATA, PIC2_OFFSET); io_wait(); // ICW3: Tell Master there is a slave at IRQ2 (0000 0100) outb(PIC1_DATA, 4); io_wait(); // ICW3: Tell Slave its cascade identity (0000 0010) outb(PIC2_DATA, 2); io_wait(); // ICW4: Set 8086/88 mode outb(PIC1_DATA, 0x01); io_wait(); outb(PIC2_DATA, 0x01); io_wait(); // Restore masks (or disable all to start clean) outb(PIC1_DATA, 0xFB); // Keep IRQ2 (cascade) open outb(PIC2_DATA, 0xFF); } void pic_send_eoi(uint8_t irq) { if (irq >= 8) { outb(PIC2_COMMAND, PIC_EOI); } outb(PIC1_COMMAND, PIC_EOI); } void pic_unmask(uint8_t irq) { uint16_t port; if (irq < 8) { port = PIC1_DATA; } else { port = PIC2_DATA; irq -= 8; } uint8_t value = inb(port) & ~(1 << irq); outb(port, value); } void pic_mask(uint8_t irq) { uint16_t port; if (irq < 8) { port = PIC1_DATA; } else { port = PIC2_DATA; irq -= 8; } uint8_t value = inb(port) | (1 << irq); outb(port, value); }