|
|
|
#include "pic.h"
|
|
|
|
#include "io.h"
|
|
|
|
|
|
|
|
void pic_send_eoi(uint8 irq) {
|
|
|
|
if( irq >= 8 )
|
|
|
|
outb(PIC2_CMD, PIC_EOI);
|
|
|
|
outb(PIC1_CMD, PIC_EOI);
|
|
|
|
}
|
|
|
|
|
|
|
|
// disable the PIC
|
|
|
|
void pic_disable() {
|
|
|
|
outb(PIC1_DATA, 0xff);
|
|
|
|
outb(PIC2_DATA, 0xff);
|
|
|
|
}
|
|
|
|
|
|
|
|
void pic_remap(uint offset_1, uint offset_2) {
|
|
|
|
// Start the init sequance
|
|
|
|
outb_w(PIC1_CMD, ICW_INIT_MASK); // write ICW1 to PIC master
|
|
|
|
outb_w(PIC2_CMD, ICW_INIT_MASK); // --||-- to PIC slave
|
|
|
|
|
|
|
|
outb_w(PIC1_DATA, offset_1); // remap master
|
|
|
|
outb_w(PIC2_DATA, offset_2); // remap slave
|
|
|
|
|
|
|
|
outb_w(PIC1_DATA, 0x04); // IRQ2 to slave
|
|
|
|
outb_w(PIC2_DATA, 0x02);
|
|
|
|
|
|
|
|
outb_w(PIC1_DATA, ICW4_8086); // write ICW4 to PIC master
|
|
|
|
outb_w(PIC2_DATA, ICW4_8086); // --||-- to PIC slave
|
|
|
|
|
|
|
|
//pic_disable();
|
|
|
|
|
|
|
|
// enable all
|
|
|
|
outb(PIC1_DATA, 0x01);
|
|
|
|
outb(PIC2_DATA, 0x01);
|
|
|
|
}
|
|
|
|
|
|
|
|
void pic_init() {
|
|
|
|
pic_remap(0x20, 0x28);
|
|
|
|
}
|
|
|
|
|
|
|
|
// (un)set a specific irq
|
|
|
|
void irq_mask(uint8 idx, bool t) {
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|