commit 97ff1cf15e62e17652fbd4b789e7c07f711c155b
parent 706e95f994b9d474d9a784683273b55a63c24b2f
Author: evenfri <evenfri256@gmail.com>
Date: Mon, 3 Aug 2026 01:41:33 +0800
feat: pit
Diffstat:
7 files changed, 84 insertions(+), 9 deletions(-)
diff --git a/dat.h b/dat.h
@@ -66,4 +66,9 @@ typedef void (*int_handler)();
#define sys_read 0
#define sys_write 1
+/* pit */
+#define pit_chan0 0x40
+#define pit_comm 0x43
+#define pit_base_freq 1193182
+
#endif /* dat_h */
diff --git a/fns.h b/fns.h
@@ -60,4 +60,8 @@ size_t vfs_write(unsigned int fd, void *buf, size_t size);
/* syscall */
void syscall_init();
+/* pit */
+void pit_init(uint32_t freq);
+void pit_sleep(uint32_t ticks_to_wait);
+
#endif /* fns_h */
diff --git a/idt.c b/idt.c
@@ -22,10 +22,8 @@ void pic_remap() {
outb(pic_1_data, 0x01); io_wait();
outb(pic_2_data, 0x01); io_wait();
- outb(pic_1_data, 0b11111101); io_wait();
+ outb(pic_1_data, 0xFC); io_wait();
outb(pic_2_data, 0xff); io_wait();
-
- asm volatile ("sti");
}
void idt_load() {
@@ -36,8 +34,6 @@ void idt_load() {
}
void idt_register(unsigned char vec, int_handler handler) {
- asm volatile ("cli");
-
unsigned int addr = (unsigned int) handler;
idt[vec].isr_low = addr & 0xffff;
@@ -45,12 +41,14 @@ void idt_register(unsigned char vec, int_handler handler) {
idt[vec].reserved = 0;
idt[vec].attr = 0x8e;
idt[vec].isr_high = addr >> 16;
-
- idt_load();
-
- asm volatile ("sti");
}
void idt_init(void) {
+ asm volatile ("cli");
+ for (int i = 0; i < 256; i++) {
+ idt_register(i, excp_handler);
+ }
+
pic_remap();
+ idt_load();
}
diff --git a/init.c b/init.c
@@ -21,12 +21,17 @@ void init() {
idt_init();
vfs_write(stdout, "idt initialized\n", 16);
+
+ pit_init(1000);
+ vfs_write(stdout, "pit initialized (freq = 1000)\n", 30);
syscall_init();
vfs_write(stdout, "syscalls initialized\n", 21);
keyboard_init();
vfs_write(stdout, "keyboard initialized\n", 21);
+
+ asm volatile ("sti");
}
void bin_init_prog() {
diff --git a/isr_stub.asm b/isr_stub.asm
@@ -0,0 +1,25 @@
+bits 32
+
+global irq0_stub
+extern pit_handler
+
+section .text
+
+irq0_stub:
+ pusha
+
+ mov ax, ds
+ push eax
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+
+ call pit_handler
+
+ pop eax
+ mov ds, ax
+ mov es, ax
+
+ popa
+ iret
diff --git a/mkfile b/mkfile
@@ -14,11 +14,13 @@ ofiles = boot.$o \
vga.$o \
gdt.$o \
idt.$o \
+ isr_stub.$o \
ints.$o \
tty.$o \
vfs.$o \
syscall_entry.$o \
syscall.$o \
+ pit.$o \
init.$o \
strlen.$o
diff --git a/pit.c b/pit.c
@@ -0,0 +1,36 @@
+#include <dat.h>
+#include <fns.h>
+
+volatile uint64_t g_ticks = 0;
+
+extern void irq0_stub(void);
+
+void pit_handler(void) {
+ g_ticks++;
+ outb(0x20, 0x20);
+}
+
+void pit_init(uint32_t freq) {
+ /* calc divisor */
+ uint32_t divisor = pit_base_freq / freq;
+
+ /* limit */
+ if (divisor > 0xffff) divisor = 0xffff;
+ if (divisor < 1) divisor = 1;
+
+ /* command byte */
+ outb(pit_comm, 0x36);
+ /* lsb */
+ outb(pit_chan0, (uint8_t)(divisor & 0xff));
+ /* msb */
+ outb(pit_chan0, (uint8_t)((divisor >> 8) & 0xff));
+
+ idt_register(0x20, irq0_stub);
+}
+
+void pit_sleep(uint32_t ticks_to_wait) {
+ uint64_t target_ticks = g_ticks + ticks_to_wait;
+ while (g_ticks < target_ticks) {
+ asm volatile ("hlt");
+ }
+}