Implemented PIC (untested code)

This commit is contained in:
Alex 2022-10-17 01:43:00 +03:00
parent 154ad1b2a9
commit c5b4666b50
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
2 changed files with 165 additions and 0 deletions

123
Core/Interrupts/8259PIC.cpp Normal file
View File

@ -0,0 +1,123 @@
#include "pic.hpp"
#include <io.h>
namespace PIC
{
PIC::PIC(uint8_t MasterCommandPort, uint8_t MasterDataPort, uint8_t SlaveCommandPort, uint8_t SlaveDataPort, uint8_t MasterOffset, uint8_t SlaveOffset)
{
this->MasterCommandPort = MasterCommandPort;
this->MasterDataPort = MasterDataPort;
this->SlaveCommandPort = SlaveCommandPort;
this->SlaveDataPort = SlaveDataPort;
this->MasterOffset = MasterOffset;
this->SlaveOffset = SlaveOffset;
MasterMask = 0xFF;
SlaveMask = 0xFF;
// ICW1
outb(MasterCommandPort, 0x11);
outb(SlaveCommandPort, 0x11);
// ICW2
outb(MasterDataPort, MasterOffset);
outb(SlaveDataPort, SlaveOffset);
// ICW3
outb(MasterDataPort, 0x04);
outb(SlaveDataPort, 0x02);
// ICW4
outb(MasterDataPort, 0x01);
outb(SlaveDataPort, 0x01);
// OCW1
outb(MasterDataPort, MasterMask);
outb(SlaveDataPort, SlaveMask);
}
PIC::~PIC()
{
outb(MasterDataPort, 0xFF);
outb(SlaveDataPort, 0xFF);
}
void PIC::Mask(uint8_t IRQ)
{
uint16_t Port;
uint8_t Value;
if (IRQ < 8)
{
Port = MasterDataPort;
Value = MasterMask & ~(1 << IRQ);
MasterMask = Value;
}
else
{
Port = SlaveDataPort;
Value = SlaveMask & ~(1 << (IRQ - 8));
SlaveMask = Value;
}
outb(Port, Value);
}
void PIC::Unmask(uint8_t IRQ)
{
uint16_t Port;
uint8_t Value;
if (IRQ < 8)
{
Port = MasterDataPort;
Value = MasterMask | (1 << IRQ);
MasterMask = Value;
}
else
{
Port = SlaveDataPort;
Value = SlaveMask | (1 << (IRQ - 8));
SlaveMask = Value;
}
outb(Port, Value);
}
void PIC::SendEOI(uint8_t IRQ)
{
if (IRQ >= 8)
outb(SlaveCommandPort, 0x20);
outb(MasterCommandPort, 0x20);
}
PIT::PIT(uint16_t Port, uint16_t Frequency)
{
this->Port = Port;
this->Frequency = Frequency;
}
PIT::~PIT()
{
}
void PIT::PrepareSleep(uint32_t Milliseconds)
{
uint16_t Divisor = 1193182 / Frequency;
uint8_t Low = (uint8_t)(Divisor & 0xFF);
uint8_t High = (uint8_t)((Divisor >> 8) & 0xFF);
outb(Port + 3, 0x36);
outb(Port + 0, Low);
outb(Port + 1, High);
}
void PIT::PerformSleep()
{
uint8_t Value = inb(Port + 0);
while (Value != 0)
Value = inb(Port + 0);
}
}

42
Core/Interrupts/pic.hpp Normal file
View File

@ -0,0 +1,42 @@
#ifndef __FENNIX_KERNEL_8259PIC_H__
#define __FENNIX_KERNEL_8259PIC_H__
#include <types.h>
namespace PIC
{
class PIC
{
private:
uint8_t MasterCommandPort;
uint8_t MasterDataPort;
uint8_t SlaveCommandPort;
uint8_t SlaveDataPort;
uint8_t MasterOffset;
uint8_t SlaveOffset;
uint8_t MasterMask;
uint8_t SlaveMask;
public:
PIC(uint8_t MasterCommandPort, uint8_t MasterDataPort, uint8_t SlaveCommandPort, uint8_t SlaveDataPort, uint8_t MasterOffset, uint8_t SlaveOffset);
~PIC();
void Mask(uint8_t IRQ);
void Unmask(uint8_t IRQ);
void SendEOI(uint8_t IRQ);
};
class PIT
{
private:
uint16_t Port;
uint16_t Frequency;
public:
PIT(uint16_t Port, uint16_t Frequency);
~PIT();
void PrepareSleep(uint32_t Milliseconds);
void PerformSleep();
};
}
#endif // !__FENNIX_KERNEL_8259PIC_H__