Files
ClassicOS/pic.c
Gregory Bowne 95372a66e6 Create pic.c
Implementation for pic.h
2026-01-28 10:47:35 -08:00

77 lines
1.6 KiB
C

#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);
}