Skip to content

Commit

Permalink
Add basic PIT implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
valtyr committed Jun 26, 2021
1 parent e24d37b commit 8f65a42
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/impl/kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "dt.h"
#include "ps2.h"
#include "rtc.h"
#include "pit.h"
#include "sb16.h"

MultibootInfo systemInfo;
Expand All @@ -13,6 +14,9 @@ extern FBImage popcorn_logo;
extern u16 popcorn_chime[];
extern u32 popcorn_chime_length;

static u8 s_pit_counter = 0;
static u8 s_swap_counter = 0;

void kernel_main(u32 magic, void *addr)
{
BIOSGreeting();
Expand All @@ -27,17 +31,20 @@ void kernel_main(u32 magic, void *addr)
InitDescriptorTables();

RTCInit();
PITInit();

// Initialize framebuffer and display greeting
FBInit(systemInfo.framebufferWidth, systemInfo.framebufferHeight, (void *)systemInfo.framebufferAddress);
FBDisplayTestPattern();
FBBlit(systemInfo.framebufferWidth / 2 - popcorn_logo.width / 2, systemInfo.framebufferHeight / 2 - popcorn_logo.height / 2, &popcorn_logo);
FBOutput();

// As of right now this shuts down the emulator
// when ESC is pressed.
PS2Init();

SB16Init();
SB16DirectPlay(popcorn_chime, popcorn_chime_length);
// SB16DirectPlay(popcorn_chime, popcorn_chime_length);

while (true)
{
Expand Down
66 changes: 66 additions & 0 deletions src/impl/kernel/pit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "pit.h"

static ISRHandler s_pit_handler = NULL;

void __pit_handler(registers_t reg)
{
if (s_pit_handler != NULL)
s_pit_handler(reg);
}

void __pit_cmd_tx(u8 cmd)
{
outb(PIT_REG_COMMAND, cmd);
}

void __pit_data_tx(u8 data, u8 counter)
{
u8 port = (counter == PIT_OCW_COUNTER_0) ? PIT_REG_COUNTER0 : ((counter == PIT_OCW_COUNTER_1) ? PIT_REG_COUNTER1 : PIT_REG_COUNTER2);
outb(port, data);
}

void __pit_start_counter(u32 freq, u8 counter, u8 mode)
{
if (freq == 0)
return;

BIOSPrintf("PIT counter %d stared with frequency %dHz\n", counter / 0x40, freq);

uint16_t divisor = (uint16_t)(1193181 / (uint16_t)freq);

// send operational command words
uint8_t ocw = 0;
ocw = (ocw & ~PIT_OCW_MASK_MODE) | mode;
ocw = (ocw & ~PIT_OCW_MASK_RL) | PIT_OCW_RL_DATA;
ocw = (ocw & ~PIT_OCW_MASK_COUNTER) | counter;
__pit_cmd_tx(ocw);

// set frequency rate
__pit_data_tx(divisor & 0xff, 0);
__pit_data_tx((divisor >> 8) & 0xff, 0);
}

void PITInit()
{
BIOSPrintf("Initializing PIT...\n");

ISRRegisterHandler(IRQ_0, __pit_handler);

__pit_start_counter(60, PIT_OCW_COUNTER_0, PIT_OCW_MODE_SQUAREWAVEGEN);

BIOSPrintf("PIT initialized\n");
}

void PITAttach(ISRHandler handler)
{
if (s_pit_handler != NULL)
{
BIOSPrint("Warning: PIT handler overwritten\n");
}
s_pit_handler = handler;
}

void PITDetach()
{
s_pit_handler = NULL;
}
39 changes: 39 additions & 0 deletions src/intf/pit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include "io.h"
#include "isr.h"

// Defines borrowed from levos
// https://github.com/levex/osdev/blob/master/include/pit.h

#define PIT_REG_COUNTER0 0x40
#define PIT_REG_COUNTER1 0x41
#define PIT_REG_COUNTER2 0x42
#define PIT_REG_COMMAND 0x43

#define PIT_OCW_MASK_BINCOUNT 1 //00000001
#define PIT_OCW_MASK_MODE 0xE //00001110
#define PIT_OCW_MASK_RL 0x30 //00110000
#define PIT_OCW_MASK_COUNTER 0xC0 //11000000

#define PIT_OCW_BINCOUNT_BINARY 0 //0
#define PIT_OCW_BINCOUNT_BCD 1 //1

#define PIT_OCW_MODE_TERMINALCOUNT 0 //0000
#define PIT_OCW_MODE_ONESHOT 0x2 //0010
#define PIT_OCW_MODE_RATEGEN 0x4 //0100
#define PIT_OCW_MODE_SQUAREWAVEGEN 0x6 //0110
#define PIT_OCW_MODE_SOFTWARETRIG 0x8 //1000
#define PIT_OCW_MODE_HARDWARETRIG 0xA //1010

#define PIT_OCW_RL_LATCH 0 //000000
#define PIT_OCW_RL_LSBONLY 0x10 //010000
#define PIT_OCW_RL_MSBONLY 0x20 //100000
#define PIT_OCW_RL_DATA 0x30 //110000

#define PIT_OCW_COUNTER_0 0 //00000000
#define PIT_OCW_COUNTER_1 0x40 //01000000
#define PIT_OCW_COUNTER_2 0x80 //10000000

void PITInit();
void PITAttach(ISRHandler);

0 comments on commit 8f65a42

Please sign in to comment.