68 lines
1.6 KiB
C
68 lines
1.6 KiB
C
|
#include "cpu/pic.h"
|
||
|
#include "cpu/io.h"
|
||
|
|
||
|
void pic_remap(uint8_t offset1, uint8_t offset2) {
|
||
|
uint8_t a1, a2;
|
||
|
|
||
|
a1 = inb(PIC1_DATA); // save masks
|
||
|
a2 = inb(PIC2_DATA);
|
||
|
|
||
|
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
|
||
|
io_wait();
|
||
|
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||
|
io_wait();
|
||
|
outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset
|
||
|
io_wait();
|
||
|
outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset
|
||
|
io_wait();
|
||
|
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
|
||
|
io_wait();
|
||
|
outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010)
|
||
|
io_wait();
|
||
|
|
||
|
outb(PIC1_DATA, ICW4_8086);
|
||
|
io_wait();
|
||
|
outb(PIC2_DATA, ICW4_8086);
|
||
|
io_wait();
|
||
|
|
||
|
outb(PIC1_DATA, a1); // restore saved masks.
|
||
|
outb(PIC2_DATA, a2);
|
||
|
}
|
||
|
|
||
|
void pic_send_eoi(uint8_t irq)
|
||
|
{
|
||
|
if(irq >= 8)
|
||
|
outb(PIC2_COMMAND,PIC_EOI);
|
||
|
|
||
|
outb(PIC1_COMMAND,PIC_EOI);
|
||
|
}
|
||
|
|
||
|
void pic_irq_set_mask(uint8_t IRQline) {
|
||
|
uint16_t port;
|
||
|
uint8_t value;
|
||
|
|
||
|
if(IRQline < 8) {
|
||
|
port = PIC1_DATA;
|
||
|
} else {
|
||
|
port = PIC2_DATA;
|
||
|
IRQline -= 8;
|
||
|
}
|
||
|
value = inb(port) | (1 << IRQline);
|
||
|
outb(port, value);
|
||
|
}
|
||
|
|
||
|
void pic_irq_clear_mask(uint8_t IRQline) {
|
||
|
uint16_t port;
|
||
|
uint8_t value;
|
||
|
|
||
|
if(IRQline < 8) {
|
||
|
port = PIC1_DATA;
|
||
|
} else {
|
||
|
port = PIC2_DATA;
|
||
|
IRQline -= 8;
|
||
|
}
|
||
|
value = inb(port) & ~(1 << IRQline);
|
||
|
outb(port, value);
|
||
|
}
|
||
|
|