-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpic.c
108 lines (93 loc) · 2.47 KB
/
pic.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stddef.h>
#include <stdint.h>
#include "pic.h"
#include "ports.h"
// Inicjuje PIC - przemapowuje
void PIC_remap(int offset1, int offset2)
{
// Zapisuje maski, żeby się nie popsuły
uint8_t temp1 = inportb(PIC1_DATA);
uint8_t temp2 = inportb(PIC2_DATA);
// Rozpoczyna proces inicjalizacji
outportb(PIC1_COMMAND, 0x11);
outportb(PIC2_COMMAND, 0x11);
// Wysyła pierwszy bajt - offsety w tablicy idt
outportb(PIC1_DATA, offset1);
outportb(PIC2_DATA, offset2);
// Wysyła drugi bajt - informacja o połączeniu
outportb(PIC1_DATA, 4);
outportb(PIC2_DATA, 2);
// Wysyła trzeci bajt - informacja o środowisku
outportb(PIC1_DATA, ICW4_8086);
outportb(PIC2_DATA, ICW4_8086);
// Przewraca maski
outportb(PIC1_DATA, temp1);
outportb(PIC2_DATA, temp2);
}
// Ustawia maskowanie przerwania
void PIC_set_mask(uint8_t irq)
{
uint8_t port = 0;
if(irq<8)
{
port = PIC1_DATA;
}
else
{
port = PIC2_DATA;
irq -= 8;
}
uint8_t mask = inportb(port);
mask = mask | (0x1 << irq);
outportb(port, mask);
}
// Usówa maskowanie przerwania
void PIC_clear_mask(uint8_t irq)
{
uint8_t port = 0;
if(irq<8)
{
port = PIC1_DATA;
}
else
{
port = PIC2_DATA;
irq -= 8;
}
uint8_t mask = inportb(port);
mask = mask & ~(0x1 << irq);
outportb(port, mask);
}
// Powiadamia kontroler/kontrolery o obsłużeniu przerwania
void PIC_end_notify(uint8_t irq)
{
if(irq<8)
{
outportb(PIC1_COMMAND, COMMAND_IRQ_END);
}
else
{
outportb(PIC2_COMMAND, COMMAND_IRQ_END);
outportb(PIC1_COMMAND, COMMAND_IRQ_END);
}
}
// Zwraca zawartość rejestru IST obu kontrolerów, przyda się do wyłapywania fałszywych przerwań
uint16_t PIC_get_isr(void)
{
outportb(PIC1_COMMAND, COMMAND_READ_ISR);
outportb(PIC2_COMMAND, COMMAND_READ_ISR);
uint8_t isr1 = inportb(PIC1_COMMAND);
uint8_t isr2 = inportb(PIC1_COMMAND);
uint16_t combined = isr1 | isr2 << 8;
return combined;
}
// Zwraca zawartość rejestru irr obu kontrolerów - przerwanie które czeka na obsłużenie
uint16_t PIC_get_irr(void)
{
outportb(PIC1_COMMAND, COMMAND_READ_IRR);
outportb(PIC2_COMMAND, COMMAND_READ_IRR);
uint8_t isr1 = inportb(PIC1_COMMAND);
uint8_t isr2 = inportb(PIC1_COMMAND);
uint16_t combined = isr1 | isr2 << 8;
return combined;
}