63 lines
1.3 KiB
C
63 lines
1.3 KiB
C
#include "pic.h"
|
|
#include "io.h"
|
|
|
|
#define PIC1_COMMAND 0x20
|
|
#define PIC1_DATA 0x21
|
|
#define PIC2_COMMAND 0xA0
|
|
#define PIC2_DATA 0xA1
|
|
|
|
#define ICW1_INIT 0x10
|
|
#define ICW1_IC4 0x01
|
|
#define ICW4_8086 0x01
|
|
|
|
void pic_remap(uint8_t master_offset, uint8_t slave_offset) {
|
|
uint8_t a1 = inb(PIC1_DATA);
|
|
uint8_t a2 = inb(PIC2_DATA);
|
|
|
|
outb(PIC1_COMMAND, ICW1_INIT | ICW1_IC4);
|
|
io_wait();
|
|
outb(PIC2_COMMAND, ICW1_INIT | ICW1_IC4);
|
|
io_wait();
|
|
|
|
outb(PIC1_DATA, master_offset);
|
|
io_wait();
|
|
outb(PIC2_DATA, slave_offset);
|
|
io_wait();
|
|
|
|
outb(PIC1_DATA, 4);
|
|
io_wait();
|
|
outb(PIC2_DATA, 2);
|
|
io_wait();
|
|
|
|
outb(PIC1_DATA, ICW4_8086);
|
|
io_wait();
|
|
outb(PIC2_DATA, ICW4_8086);
|
|
io_wait();
|
|
|
|
outb(PIC1_DATA, a1);
|
|
outb(PIC2_DATA, a2);
|
|
}
|
|
|
|
void pic_set_mask(uint8_t irq_line) {
|
|
uint16_t port;
|
|
if (irq_line < 8) {
|
|
port = PIC1_DATA;
|
|
} else {
|
|
port = PIC2_DATA;
|
|
irq_line -= 8;
|
|
}
|
|
uint8_t value = inb(port) | (1 << irq_line);
|
|
outb(port, value);
|
|
}
|
|
|
|
void pic_clear_mask(uint8_t irq_line) {
|
|
uint16_t port;
|
|
if (irq_line < 8) {
|
|
port = PIC1_DATA;
|
|
} else {
|
|
port = PIC2_DATA;
|
|
irq_line -= 8;
|
|
}
|
|
uint8_t value = inb(port) & ~(1 << irq_line);
|
|
outb(port, value);
|
|
}
|