Initial timer and keyboard mapping
This commit is contained in:
parent
f671adba06
commit
402211c038
@ -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 \
|
||||||
|
@ -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
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
@ -44,6 +44,4 @@ static char* err_msg[] = {
|
|||||||
"#CP Control Protection Exception!"
|
"#CP Control Protection Exception!"
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char readkey();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
3
kernel/include/rockos/keyboard.h
Normal file
3
kernel/include/rockos/keyboard.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
void keyboard_handler(void* frame);
|
||||||
|
unsigned char readkey();
|
||||||
|
void initialize_keyset();
|
16
kernel/include/rockos/timer.h
Normal file
16
kernel/include/rockos/timer.h
Normal 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();
|
@ -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,14 +13,25 @@ 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
86
kernel/rockos/keyboard.c
Normal 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;
|
||||||
|
}
|
@ -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
26
kernel/rockos/timer.c
Normal 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;
|
||||||
|
}
|
Reference in New Issue
Block a user