Initial timer and keyboard mapping
This commit is contained in:
parent
f671adba06
commit
402211c038
@ -31,6 +31,8 @@ KERNEL_OBJS=\
|
||||
$(KERNEL_ARCH_OBJS) \
|
||||
rockos/kernel.o \
|
||||
rockos/paging.o \
|
||||
rockos/keyboard.o \
|
||||
rockos/timer.o \
|
||||
|
||||
OBJS=\
|
||||
$(ARCHDIR)/boot/crti.o \
|
||||
|
@ -1,18 +1,8 @@
|
||||
#include <rockos/idt.h>
|
||||
#include <rockos/pic.h>
|
||||
#include <rockos/keyboard.h>
|
||||
#include <rockos/timer.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) {
|
||||
if (number <= 21) {
|
||||
printf("%s\n", err_msg[number]);
|
||||
@ -107,7 +97,9 @@ void idt_init(void) {
|
||||
idt_set_descriptor(29, int29_wrapper, 0x8E);
|
||||
idt_set_descriptor(30, int30_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);
|
||||
|
||||
__asm__ volatile("lidt %0" : : "m"(idtptr)); // Load new IDT
|
||||
|
@ -23,8 +23,6 @@ void PIC_remap() {
|
||||
outb(PIC2_DATA, ICW4_8086);
|
||||
io_wait();
|
||||
|
||||
outb(PIC1_DATA, 0xFF); // restore saved masks
|
||||
outb(PIC2_DATA, 0xFF);
|
||||
|
||||
outb(PIC1_DATA, 0xFD); // Keyboard IRQ
|
||||
outb(PIC1_DATA, 0); // ALL THE INTERRUPTS
|
||||
outb(PIC2_DATA, 0);
|
||||
}
|
@ -44,6 +44,4 @@ static char* err_msg[] = {
|
||||
"#CP Control Protection Exception!"
|
||||
};
|
||||
|
||||
unsigned char readkey();
|
||||
|
||||
#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 <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) {
|
||||
printf("Hello, kernel World!\n");
|
||||
@ -10,14 +13,25 @@ void kernel_main(void) {
|
||||
printf("Int test: %d\n", 747474);
|
||||
printf("Hex test: 0x%x\n", 0xDEADBEEF);
|
||||
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 key = readkey();
|
||||
for(;;){
|
||||
oldkey = key;
|
||||
key = readkey();
|
||||
if (key != oldkey)
|
||||
if (key != '\0') {
|
||||
putchar(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 <stdint.h>
|
||||
|
||||
void load_page_dir(uint32_t page_dir) {
|
||||
void load_page_dir(uint32_t* page_dir) {
|
||||
asm volatile (
|
||||
"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