A poorly written OS for the x86 arch. (WIP)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
eOS/kernel/pic.c

71 lines
1.2 KiB

3 years ago
#include "pic.h"
3 years ago
#include "io.h"
3 years ago
3 years ago
void pic_send_eoi(uint8 irq) {
3 years ago
if( irq >= 8 )
3 years ago
outb(PIC2_CMD, PIC_EOI);
outb(PIC1_CMD, PIC_EOI);
3 years ago
}
3 years ago
void pic_remap(uint offset_1, uint offset_2) {
3 years ago
// Start the init sequance
3 years ago
outb_w(PIC1_CMD, ICW_INIT_MASK);
3 years ago
3 years ago
outb_w(PIC2_CMD, ICW_INIT_MASK);
3 years ago
3 years ago
outb_w(PIC1_DATA, offset_1);
outb_w(PIC2_DATA, offset_2);
3 years ago
3 years ago
outb_w(PIC1_DATA, 0x4);
3 years ago
outb_w(PIC2_DATA, 0x2);
3 years ago
outb_w(PIC1_DATA, ICW4_8086);
outb_w(PIC2_DATA, ICW4_8086);
outb(PIC1_DATA, 0xff);
outb(PIC2_DATA, 0xff);
3 years ago
}
// disable the PIC
// will probably never use this.
3 years ago
void pic_disable() {
outb(PIC1_DATA, 0xff);
outb(PIC2_DATA, 0xff);
3 years ago
}
3 years ago
3 years ago
void pic_init() {
pic_remap(PIC1, PIC2);
}
3 years ago
// (un)set a specific irq
void irq_mask(uint8 idx, bool t) {
3 years ago
uint16 port;
uint8 data;
if(idx < 8) {
port = PIC1_DATA;
} else {
port = PIC2_DATA;
idx -= 8;
}
if( t == true ) { // set irq
data = inb(port) | (1 << idx);
outb(port, data);
} else { // clear irq
data = inb(port) & ~(1 << idx);
outb(port, data);
}
}
3 years ago
static uint16 irq_reg(int ocw3) {
outb(PIC1_CMD, ocw3);
outb(PIC2_CMD, ocw3);
return (inb(PIC2_CMD) << 8 | inb(PIC1_CMD));
}
uint16 get_irr() { return irq_reg(PIC_R_IRR); } // fetch IRR
uint16 get_isr() { return irq_reg(PIC_R_ISR); } // fetch ISR