mirror of
https://github.com/gbowne1/ClassicOS.git
synced 2026-02-15 14:55:20 -08:00
Create pic.c
Implementation for pic.h
This commit is contained in:
76
pic.c
Normal file
76
pic.c
Normal file
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user