Files

59 lines
1.9 KiB
C

#include "../includes/pic.h"
#include "../includes/io.h"
#include "../includes/idt.h"
#include "../includes/irq.h"
#define PIC1_PORT 0x20
#define PIC1_DATA_PORT 0X21
#define PIC2_PORT 0xA0
#define PIC2_DATA_PORT 0XA1
#define PIC1_START_INTERRUPT 0x20
#define PIC2_START_INTERRUPT 0x28
#define PIC2_END_INTERRUPT PIC2_START_INTERRUPT + 7
#define PIC_ACK 0x20
void pic_acknowledge(unsigned int interrupt_no)
{
if (interrupt_no < PIC2_START_INTERRUPT)
outb(PIC1_PORT, PIC_ACK);
else
outb(PIC2_PORT, PIC_ACK);
}
void setup_pics(void)
{
// The PIC uses Initialization Command Words (ICW) to communicate.
// So we start with the first ICW, 0x11, this tells the PIC to expect
// 3 more ICWs.
outb(PIC1_PORT, 0x11);
outb(PIC2_PORT, 0x11);
// This tells the pic what offset to use when it generates the interrupt numbers.
// Since the first 32 ISRs are reserved by the CPU we must start at IRS32 and work
// our way up. When the PIC recieves an interrupt on it's input line, it will add
// the supplied values to that number before sending the newly made number to the CPU.
// Thereby remapping an interrupt number that would have normally conflicted with the
// values in the IDT.
outb(PIC1_DATA_PORT, PIC1_START_INTERRUPT);
outb(PIC2_DATA_PORT, PIC2_START_INTERRUPT);
// This ICW allows for cascading of their outputs to inputs between each other.
// I'm not sure what that really means but at this current time I'm not going to
// be doing this, so the bits will all be set to zero.
outb(PIC1_DATA_PORT, 0x00);
outb(PIC2_DATA_PORT, 0x00);
// This is the environment info, and setting the lowest bit tells the PICs
// that we're running in 80x86 mode.
outb(PIC1_DATA_PORT, 0x01);
outb(PIC2_DATA_PORT, 0x01);
// Finally, we have the interrupt masks.
outb(PIC1_DATA_PORT, 0xFF);
outb(PIC2_DATA_PORT, 0xFF);
idt_set_gate(33, (unsigned long) &irq1, 0x08, 0x8E);
}