Skip to content

Commit fc2c225

Browse files
committed
Add basic PIT implementation
1 parent e24d37b commit fc2c225

File tree

3 files changed

+113
-1
lines changed

3 files changed

+113
-1
lines changed

src/impl/kernel/main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "dt.h"
55
#include "ps2.h"
66
#include "rtc.h"
7+
#include "pit.h"
78
#include "sb16.h"
89

910
MultibootInfo systemInfo;
@@ -13,6 +14,9 @@ extern FBImage popcorn_logo;
1314
extern u16 popcorn_chime[];
1415
extern u32 popcorn_chime_length;
1516

17+
static u8 s_pit_counter = 0;
18+
static u8 s_swap_counter = 0;
19+
1620
void kernel_main(u32 magic, void *addr)
1721
{
1822
BIOSGreeting();
@@ -27,17 +31,20 @@ void kernel_main(u32 magic, void *addr)
2731
InitDescriptorTables();
2832

2933
RTCInit();
34+
PITInit();
3035

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

42+
// As of right now this shuts down the emulator
43+
// when ESC is pressed.
3744
PS2Init();
3845

3946
SB16Init();
40-
SB16DirectPlay(popcorn_chime, popcorn_chime_length);
47+
// SB16DirectPlay(popcorn_chime, popcorn_chime_length);
4148

4249
while (true)
4350
{

src/impl/kernel/pit.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "pit.h"
2+
3+
static ISRHandler s_pit_handler = NULL;
4+
5+
void __pit_handler(registers_t reg)
6+
{
7+
if (s_pit_handler != NULL)
8+
s_pit_handler(reg);
9+
}
10+
11+
void __pit_cmd_tx(u8 cmd)
12+
{
13+
outb(PIT_REG_COMMAND, cmd);
14+
}
15+
16+
void __pit_data_tx(u8 data, u8 counter)
17+
{
18+
u8 port = (counter == PIT_OCW_COUNTER_0) ? PIT_REG_COUNTER0 : ((counter == PIT_OCW_COUNTER_1) ? PIT_REG_COUNTER1 : PIT_REG_COUNTER2);
19+
outb(port, data);
20+
}
21+
22+
void __pit_start_counter(u32 freq, u8 counter, u8 mode)
23+
{
24+
if (freq == 0)
25+
return;
26+
27+
BIOSPrintf("PIT counter %d started with frequency %dHz\n", counter / 0x40, freq);
28+
29+
uint16_t divisor = (uint16_t)(1193181 / (uint16_t)freq);
30+
31+
// send operational command words
32+
uint8_t ocw = 0;
33+
ocw = (ocw & ~PIT_OCW_MASK_MODE) | mode;
34+
ocw = (ocw & ~PIT_OCW_MASK_RL) | PIT_OCW_RL_DATA;
35+
ocw = (ocw & ~PIT_OCW_MASK_COUNTER) | counter;
36+
__pit_cmd_tx(ocw);
37+
38+
// set frequency rate
39+
__pit_data_tx(divisor & 0xff, 0);
40+
__pit_data_tx((divisor >> 8) & 0xff, 0);
41+
}
42+
43+
void PITInit()
44+
{
45+
BIOSPrintf("Initializing PIT...\n");
46+
47+
ISRRegisterHandler(IRQ_0, __pit_handler);
48+
49+
__pit_start_counter(60, PIT_OCW_COUNTER_0, PIT_OCW_MODE_SQUAREWAVEGEN);
50+
51+
BIOSPrintf("PIT initialized\n");
52+
}
53+
54+
void PITAttach(ISRHandler handler)
55+
{
56+
if (s_pit_handler != NULL)
57+
{
58+
BIOSPrint("Warning: PIT handler overwritten\n");
59+
}
60+
s_pit_handler = handler;
61+
}
62+
63+
void PITDetach()
64+
{
65+
s_pit_handler = NULL;
66+
}

src/intf/pit.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include "io.h"
4+
#include "isr.h"
5+
6+
// Defines borrowed from levos
7+
// https://github.com/levex/osdev/blob/master/include/pit.h
8+
9+
#define PIT_REG_COUNTER0 0x40
10+
#define PIT_REG_COUNTER1 0x41
11+
#define PIT_REG_COUNTER2 0x42
12+
#define PIT_REG_COMMAND 0x43
13+
14+
#define PIT_OCW_MASK_BINCOUNT 1 //00000001
15+
#define PIT_OCW_MASK_MODE 0xE //00001110
16+
#define PIT_OCW_MASK_RL 0x30 //00110000
17+
#define PIT_OCW_MASK_COUNTER 0xC0 //11000000
18+
19+
#define PIT_OCW_BINCOUNT_BINARY 0 //0
20+
#define PIT_OCW_BINCOUNT_BCD 1 //1
21+
22+
#define PIT_OCW_MODE_TERMINALCOUNT 0 //0000
23+
#define PIT_OCW_MODE_ONESHOT 0x2 //0010
24+
#define PIT_OCW_MODE_RATEGEN 0x4 //0100
25+
#define PIT_OCW_MODE_SQUAREWAVEGEN 0x6 //0110
26+
#define PIT_OCW_MODE_SOFTWARETRIG 0x8 //1000
27+
#define PIT_OCW_MODE_HARDWARETRIG 0xA //1010
28+
29+
#define PIT_OCW_RL_LATCH 0 //000000
30+
#define PIT_OCW_RL_LSBONLY 0x10 //010000
31+
#define PIT_OCW_RL_MSBONLY 0x20 //100000
32+
#define PIT_OCW_RL_DATA 0x30 //110000
33+
34+
#define PIT_OCW_COUNTER_0 0 //00000000
35+
#define PIT_OCW_COUNTER_1 0x40 //01000000
36+
#define PIT_OCW_COUNTER_2 0x80 //10000000
37+
38+
void PITInit();
39+
void PITAttach(ISRHandler);

0 commit comments

Comments
 (0)