From 95372a66e6278f723e20468b1625d3d2b5acd121 Mon Sep 17 00:00:00 2001 From: Gregory Bowne Date: Wed, 28 Jan 2026 10:47:35 -0800 Subject: [PATCH] Create pic.c Implementation for pic.h --- pic.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 pic.c diff --git a/pic.c b/pic.c new file mode 100644 index 0000000..457ffe8 --- /dev/null +++ b/pic.c @@ -0,0 +1,76 @@ +#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); +}