From 11ced165e0df11cc3c889eb0cc402467361c421b Mon Sep 17 00:00:00 2001 From: Aleksa Vuckovic Date: Thu, 1 Sep 2022 23:45:47 +0200 Subject: timer & stdbuff --- kernel/Makefile | 2 ++ kernel/include/stdbuff.h | 18 ++++++++++++++++++ kernel/include/timer.h | 11 +++++++++++ kernel/src/cpu/irq.c | 2 ++ kernel/src/cpu/pic.c | 2 +- kernel/src/devices/keyboard.c | 41 ++++++++++++++++++++++++++++++----------- kernel/src/devices/timer.c | 27 +++++++++++++++++++++++++++ kernel/src/main.c | 3 ++- kernel/src/misc/stdbuff.c | 30 ++++++++++++++++++++++++++++++ 9 files changed, 123 insertions(+), 13 deletions(-) create mode 100644 kernel/include/stdbuff.h create mode 100644 kernel/include/timer.h create mode 100644 kernel/src/devices/timer.c create mode 100644 kernel/src/misc/stdbuff.c diff --git a/kernel/Makefile b/kernel/Makefile index af14226..9516567 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -12,6 +12,7 @@ OBJS = \ src/cpu/pic.o \ src/devices/disc.o \ src/devices/keyboard.o \ + src/devices/timer.o \ src/fs/ext2.o \ src/libk/list.o \ src/libk/math.o \ @@ -23,6 +24,7 @@ OBJS = \ src/mem/paging.o \ src/misc/debug.o \ src/misc/graphics.o \ + src/misc/stdbuff.o \ all: kernel.bin diff --git a/kernel/include/stdbuff.h b/kernel/include/stdbuff.h new file mode 100644 index 0000000..908fee2 --- /dev/null +++ b/kernel/include/stdbuff.h @@ -0,0 +1,18 @@ +#ifndef STDBUFF_H +#define STDBUFF_H + +#include + +struct stdbuff { + size_t head; + size_t tail; + uint32_t size; + char* data; +}; +typedef struct stdbuff stdbuff; + +stdbuff* init_buff(uint32_t buff_size); +void read_buff(stdbuff* buffer, char* dest_ptr, size_t read_size); +void write_buff(stdbuff* buffer, const char* src_ptr, size_t write_size); + +#endif diff --git a/kernel/include/timer.h b/kernel/include/timer.h new file mode 100644 index 0000000..0113bbb --- /dev/null +++ b/kernel/include/timer.h @@ -0,0 +1,11 @@ +#ifndef TIMER_H +#define TIMER_H + +#include + +#define TICKS_PER_SECOND 50 + +void timer_handler(void); +void init_timer(uint32_t frequency); + +#endif diff --git a/kernel/src/cpu/irq.c b/kernel/src/cpu/irq.c index dd87b61..096860a 100644 --- a/kernel/src/cpu/irq.c +++ b/kernel/src/cpu/irq.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -214,6 +215,7 @@ void isr31_handler(void) void irq0_handler(void) { + timer_handler(); outb(PIC1_COMMAND, PIC_EOI); } diff --git a/kernel/src/cpu/pic.c b/kernel/src/cpu/pic.c index 801556d..ceb6e11 100644 --- a/kernel/src/cpu/pic.c +++ b/kernel/src/cpu/pic.c @@ -19,6 +19,6 @@ void remap_pic(void) outb(PIC2_DATA, ICW4_8086); // mask interrupts - outb(PIC1_DATA, 0xfd); + outb(PIC1_DATA, 0xfc); outb(PIC2_DATA, 0xff); } diff --git a/kernel/src/devices/keyboard.c b/kernel/src/devices/keyboard.c index f39f978..60f41b8 100644 --- a/kernel/src/devices/keyboard.c +++ b/kernel/src/devices/keyboard.c @@ -1,42 +1,61 @@ #include #include - #include #include #include #include #include - -#define KEYBOARD_DATA_PORT 0x60 -#define KEYBOARD_STATUS_PORT 0x64 +#include bool is_pressed[128]; -void keyboard_handler(void) +#include +#include +#define BUFFER_SIZE 10000 +stdbuff* keyboard_buffer; + +void keyboard_handler() { + if (keyboard_buffer == NULL) { + keyboard_buffer = init_buff(BUFFER_SIZE); + memset(keyboard_buffer->data, ' ', BUFFER_SIZE); + } + uint8_t status = inb(KEYBOARD_STATUS_PORT); if (!(status & 0x1)) { return; } + uint8_t keycode = inb(KEYBOARD_DATA_PORT); + if (keycode < keymap_len) { is_pressed[keycode] = true; if (keycode == KEY_SPACE) { - printf(" "); - + write_buff(keyboard_buffer, " ", 1); } else if (keycode == KEY_BACKSPACE) { if (curr_x != 0) - printf("\b \b"); + write_buff(keyboard_buffer, "\b \b", 3); } else if (keycode == KEY_ENTER) { - printf("%c", keymap[keycode]); + char* output = kalloc(sizeof(char) + 1); + output[0] = keymap[keycode]; + write_buff(keyboard_buffer, output, 1); + kfree(output); } else { + char* output = kalloc(sizeof(char) + 1); if (keymap[keycode] == ' ') return; if (is_pressed[KEY_LSHIFT] || is_pressed[KEY_RSHIFT]) - printf("%c", shift_keymap[keycode]); + output[0] = shift_keymap[keycode]; else - printf("%c", keymap[keycode]); + output[0] = keymap[keycode]; + write_buff(keyboard_buffer, output, 1); + kfree(output); } } else { is_pressed[keycode - 128] = false; } + + uint32_t len = (uint32_t)(keyboard_buffer->head - keyboard_buffer->tail); + char* print_buff = kalloc(len + 1); + read_buff(keyboard_buffer, print_buff, len); + printf("%s", print_buff); } diff --git a/kernel/src/devices/timer.c b/kernel/src/devices/timer.c new file mode 100644 index 0000000..1291219 --- /dev/null +++ b/kernel/src/devices/timer.c @@ -0,0 +1,27 @@ +#include +#include +#include + +uint32_t tick = 0; +uint32_t seconds = 0; + +void timer_handler() +{ + tick++; + if (tick > TICKS_PER_SECOND) { + tick = 0; + seconds++; + } +} + +void init_timer(uint32_t frequency) +{ + uint32_t divisor = 1193180 / frequency; + outb(0x43, 0x36); + + uint8_t l = (uint8_t)(divisor & 0xFF); + uint8_t h = (uint8_t)((divisor>>8) & 0xFF); + + outb(0x40, l); + outb(0x40, h); +} diff --git a/kernel/src/main.c b/kernel/src/main.c index ce307e2..c575a0e 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -1,5 +1,4 @@ #include - #include #include #include @@ -11,12 +10,14 @@ #include #include #include +#include int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic); int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) { init_paging(); init_idt(); + init_timer(TICKS_PER_SECOND); init_heap(); read_mb2(multiboot_bootinfo, multiboot_magic); diff --git a/kernel/src/misc/stdbuff.c b/kernel/src/misc/stdbuff.c new file mode 100644 index 0000000..cca58d6 --- /dev/null +++ b/kernel/src/misc/stdbuff.c @@ -0,0 +1,30 @@ +#include +#include +#include + +stdbuff* init_buff(uint32_t buff_size) +{ + stdbuff* buffer = kalloc(sizeof(stdbuff)); + buffer->head = 0; + buffer->tail = 0; + buffer->size = buff_size; + buffer->data = kalloc(buffer->size); + return buffer; +} + +void read_buff(stdbuff* buffer, char* dest_ptr, size_t read_size) +{ + for (size_t i = 0; i < read_size; i++) { + memcpy(dest_ptr + i, buffer->data + ((buffer->tail + i) % buffer->size), 1); + } + dest_ptr[read_size] = '\0'; + buffer->tail = (buffer->tail + read_size) % buffer->size; +} + +void write_buff(stdbuff* buffer, const char* src_ptr, size_t write_size) +{ + for (size_t i = 0; i < write_size; i++) { + memcpy(buffer->data + ((buffer->head + i) % buffer->size), src_ptr + i, 1); + } + buffer->head = (buffer->head + write_size) % buffer->size; +} -- cgit v1.2.3