Initial timer and keyboard mapping

This commit is contained in:
Furkan Mudanyali 2022-07-21 12:20:35 +03:00
parent f671adba06
commit 402211c038
11 changed files with 157 additions and 22 deletions

View File

@ -31,6 +31,8 @@ KERNEL_OBJS=\
$(KERNEL_ARCH_OBJS) \ $(KERNEL_ARCH_OBJS) \
rockos/kernel.o \ rockos/kernel.o \
rockos/paging.o \ rockos/paging.o \
rockos/keyboard.o \
rockos/timer.o \
OBJS=\ OBJS=\
$(ARCHDIR)/boot/crti.o \ $(ARCHDIR)/boot/crti.o \

View File

@ -1,18 +1,8 @@
#include <rockos/idt.h> #include <rockos/idt.h>
#include <rockos/pic.h> #include <rockos/keyboard.h>
#include <rockos/timer.h>
#include <stdio.h> #include <stdio.h>
static unsigned char key;
__attribute__((interrupt)) void keyboard_handler(void* frame) {
key = inb(0x60);
outb(0x20, 0x20);
}
unsigned char readkey() {
return key;
}
__attribute__((interrupt)) void int_handler(void* frame, unsigned int number) { __attribute__((interrupt)) void int_handler(void* frame, unsigned int number) {
if (number <= 21) { if (number <= 21) {
printf("%s\n", err_msg[number]); printf("%s\n", err_msg[number]);
@ -107,7 +97,9 @@ void idt_init(void) {
idt_set_descriptor(29, int29_wrapper, 0x8E); idt_set_descriptor(29, int29_wrapper, 0x8E);
idt_set_descriptor(30, int30_wrapper, 0x8E); idt_set_descriptor(30, int30_wrapper, 0x8E);
idt_set_descriptor(31, int31_wrapper, 0x8E); idt_set_descriptor(31, int31_wrapper, 0x8E);
// IRQs
idt_set_descriptor(32, timer_handler, 0x8E);
timer_phase(100);
idt_set_descriptor(33, keyboard_handler, 0x8E); idt_set_descriptor(33, keyboard_handler, 0x8E);
__asm__ volatile("lidt %0" : : "m"(idtptr)); // Load new IDT __asm__ volatile("lidt %0" : : "m"(idtptr)); // Load new IDT

View File

@ -23,8 +23,6 @@ void PIC_remap() {
outb(PIC2_DATA, ICW4_8086); outb(PIC2_DATA, ICW4_8086);
io_wait(); io_wait();
outb(PIC1_DATA, 0xFF); // restore saved masks outb(PIC1_DATA, 0); // ALL THE INTERRUPTS
outb(PIC2_DATA, 0xFF); outb(PIC2_DATA, 0);
outb(PIC1_DATA, 0xFD); // Keyboard IRQ
} }

View File

@ -44,6 +44,4 @@ static char* err_msg[] = {
"#CP Control Protection Exception!" "#CP Control Protection Exception!"
}; };
unsigned char readkey();
#endif #endif

View File

@ -0,0 +1,3 @@
void keyboard_handler(void* frame);
unsigned char readkey();
void initialize_keyset();

View File

@ -0,0 +1,16 @@
#include <stdint.h>
#define SUBTICKS_PER_TICK 100
#define PIT_0 0x40
#define PIT_1 0x41
#define PIT_2 0x42
#define PIT_CONTROL 0x43
#define PIT_MASK 0xFF
#define PIT_SCALE 1193180
#define PIT_SET 0x36
void timer_phase(uint32_t hz);
void timer_handler(void* frame);
uint64_t get_ticks();

View File

@ -1,7 +1,10 @@
#include <stdio.h> #include <stdio.h>
#include <rockos/tty.h> #include <rockos/tty.h>
#include <rockos/gdt.h> #include <rockos/keyboard.h>
#include <rockos/pic.h>
#include <rockos/hal.h>
#include <rockos/timer.h>
void kernel_main(void) { void kernel_main(void) {
printf("Hello, kernel World!\n"); printf("Hello, kernel World!\n");
@ -10,15 +13,26 @@ void kernel_main(void) {
printf("Int test: %d\n", 747474); printf("Int test: %d\n", 747474);
printf("Hex test: 0x%x\n", 0xDEADBEEF); printf("Hex test: 0x%x\n", 0xDEADBEEF);
printf("And now for 0.1 + 0.2...... which is: %.17f\n", 0.1 + 0.2); printf("And now for 0.1 + 0.2...... which is: %.17f\n", 0.1 + 0.2);
initialize_keyset();
outb(0x70, (0x80 << 7) | 0x0); // Seconds
uint8_t sec = inb(0x71);
outb(0x70, (0x80 << 7) | 0x02); // Minutes
uint8_t min = inb(0x71);
outb(0x70, (0x80 << 7) | 0x04); // Hours
uint8_t hour = inb(0x71);
printf("Time: %x:%x:%x\n", hour, min, sec);
unsigned char oldkey; unsigned char oldkey;
unsigned char key = readkey(); unsigned char key = readkey();
for(;;){ for(;;){
oldkey = key; oldkey = key;
key = readkey(); key = readkey();
if (key != oldkey) if (key != '\0') {
putchar(key); putchar(key);
} }
}
asm("cli; hlt"); asm("cli; hlt");
} }

86
kernel/rockos/keyboard.c Normal file
View File

@ -0,0 +1,86 @@
#include <rockos/keyboard.h>
#include <rockos/pic.h>
#include <rockos/timer.h>
#include <rockos/hal.h>
#include <string.h>
#define ESC_P 0x01
#define BACKSPACE_P 0x0F
#define ENTER_P 0x1C
#define LEFT_C_P 0x1D
#define LEFT_SHIFT_P 0x2B
#define RIGHT_SHIFT_P 0x36
#define LEFT_ALT_P 0x38
#define CAPS_LCK_P 0x3A
static unsigned char interrupt_key;
static uint8_t keyset[89];
static uint64_t keytimes[89];
static unsigned char keymap[89] = {
0, ESC_P, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', BACKSPACE_P,
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', ENTER_P, LEFT_C_P,
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', LEFT_SHIFT_P, '\\',
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', RIGHT_SHIFT_P, '*', LEFT_ALT_P, ' ', CAPS_LCK_P
};
void initialize_keyset() {
//for(int i = 0; i < 89; ++i) keyset[i] = 0;
memset(keyset, 0, 89);
memset(keytimes, 0, 89);
}
__attribute__((interrupt)) void keyboard_handler(void* frame) {
interrupt_key = inb(0x60);
pic_eoi(1);
if((interrupt_key & 128) == 128){
keyset[interrupt_key - 0x80] = 0;
keytimes[interrupt_key - 0x80] = 0;
} else {
if(keyset[interrupt_key] == 2)
return;
keyset[interrupt_key] = 1;
}
}
unsigned char readkey() {
uint8_t shift_pressed = 0;
if (keyset[LEFT_SHIFT_P] || keyset[RIGHT_SHIFT_P])
shift_pressed = 1;
for(uint8_t i = 0; i < 89; ++i) {
switch(i) {
case ESC_P:
case LEFT_C_P:
case LEFT_SHIFT_P:
case RIGHT_SHIFT_P:
case LEFT_ALT_P:
case CAPS_LCK_P:
continue;
}
if (keyset[i]){
uint64_t temptime = get_ticks();
if(keytimes[i]) {
if(keyset[i] == 1) {
if(temptime - keytimes[i] < 20) {
return 0;
} else {
keyset[i] = 2;
//return 0;
}
} else {
if(temptime - keytimes[i] < 5) {
return 0;
}
}
}
keytimes[i] = temptime;
if (shift_pressed && (keymap[i] > 0x60 && keymap[i] < 0x7A)) {
return keymap[i] - 0x20;
} else {
return keymap[i];
}
}
}
return 0;
}

View File

@ -1,7 +1,7 @@
#include <rockos/paging.h> #include <rockos/paging.h>
#include <stdint.h> #include <stdint.h>
void load_page_dir(uint32_t page_dir) { void load_page_dir(uint32_t* page_dir) {
asm volatile ( asm volatile (
"mov %%eax, %%cr3" "mov %%eax, %%cr3"
: :

26
kernel/rockos/timer.c Normal file
View File

@ -0,0 +1,26 @@
#include <rockos/timer.h>
#include <rockos/hal.h>
#include <rockos/pic.h>
#include <stdio.h>
uint64_t ticks = 0;
uint8_t subticks = 0;
__attribute__((interrupt)) void timer_handler(void* frame) {
if(++subticks == SUBTICKS_PER_TICK) {
++ticks;
subticks = 0;
}
pic_eoi(0);
}
void timer_phase(uint32_t hz) {
uint32_t divisor = PIT_SCALE / hz;
outb(PIT_CONTROL, PIT_SET);
outb(PIT_0, divisor & PIT_MASK);
outb(PIT_0, (divisor >> 8) & PIT_MASK);
}
uint64_t get_ticks() {
return ticks*100 + subticks;
}