From d9d3abbf620881d20fc3479f5c4992b368f0f7e5 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Thu, 2 Sep 2021 20:59:15 +0100 Subject: [PATCH] Moved IDT code wholely to idt.c, add keyboard read support, add readline function, updated Makefile accordingly. --- Makefile | 2 +- idt.c | 18 +++++++++++ kernel32.c | 49 +++++++++++++++++++---------- keyboard.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ keyboard.h | 12 ++++++++ 5 files changed, 154 insertions(+), 17 deletions(-) create mode 100644 keyboard.c create mode 100644 keyboard.h diff --git a/Makefile b/Makefile index 27bd7ea..e03c67f 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CFLAGS = -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exceptions -fno-le LDFLAGS = DISK_IMG_FILES = kernel.bin hello.bin print.bin boot32.bin kernel32.bin -KERNEL32_OBJS = screenstuff.o io.o idt.o kernel32_strap.o kernel32.o +KERNEL32_OBJS = screenstuff.o io.o idt.o keyboard.o kernel32_strap.o kernel32.o run: disk.img qemu-system-x86_64 disk.img diff --git a/idt.c b/idt.c index 71d71f3..2bdadae 100644 --- a/idt.c +++ b/idt.c @@ -14,6 +14,11 @@ void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, u }; } +__attribute__((interrupt)) void interrupt_20(struct interrupt_frame* frame) { +// printf("Interrupt 20 received!!\n"); + outb(0x20, 0x20); +} + __attribute__((interrupt)) void ignore_interrupt(struct interrupt_frame* frame) { // Do nothing } @@ -23,6 +28,19 @@ void init_idt() { asm volatile("lidt %0" : : "m" (desc)); for (int i=0; i<256; i++) set_entry(i, 0x08, &ignore_interrupt, 0x8E); + + set_entry(0x20, 0x08, &interrupt_20, 0x8E); + + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, 0x28); + outb(0x21, 0x04); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x00); + outb(0xA1, 0x00); } void enable_idt() { diff --git a/kernel32.c b/kernel32.c index a75dcf0..552267e 100644 --- a/kernel32.c +++ b/kernel32.c @@ -2,33 +2,50 @@ #include "screenstuff.h" #include "io.h" #include "idt.h" +#include "keyboard.h" -__attribute__((interrupt)) void interrupt_21(struct interrupt_frame* frame) { - printf("Interrupt 20 received!!\n"); - outb(0x20, 0x20); +bool strcmp(char* a, char* b, int max) { + int index = 0; + while (index < max) { + if (a[index] != b[index]) + return false; + index++; + } + return true; } int main() { init_idt(); - set_entry(0x20, 0x08, &interrupt_21, 0x8E); init_term(); printf("KERNEL32 OK!\n"); printf("Hello, World!\n\nWe are running XnoeOS Code in C now, Protected Mode has been achieved and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n"); - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, 0x28); - outb(0x21, 0x04); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x00); - outb(0xA1, 0x00); - + init_keyboard(); enable_idt(); - while (1); + + while (1) { + printf(">>> "); + char buffer[128]; + for (int i=0; i<128; i++) + buffer[i] = 0; + readline(128, buffer); + + //printf("%s\n", buffer); + if (strcmp(buffer, "help", 4)) { + printf( + "XnoeOS 32 Bit Mode Help.\n" + "------------------------\n" + "- help\n" + ": Shows this message\n" + "- clear\n" + ": Clears the screen\n" + ); + } else if (strcmp(buffer, "clear", 5)) { + clear_screen(); + set_curpos(0, 0); + } + } } \ No newline at end of file diff --git a/keyboard.c b/keyboard.c new file mode 100644 index 0000000..870f68c --- /dev/null +++ b/keyboard.c @@ -0,0 +1,90 @@ +#include "keyboard.h" + + +char key_to_char[128] = { + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0, + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', + 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', + '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +char key_to_char_caps[128] = { + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0, + 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\', + 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', + '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +char key_to_char_shift[128] = { + 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0, + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0, + 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', + 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', + '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; + +uint8_t current_scancode = 0; + +__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame) { + current_scancode = inb(0x60); + outb(0x20, 0x21); +} + +void init_keyboard() { + set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E); + + while (inb(0x64) & 1) { + inb(0x60); + } + + outb(0x64, 0xAE); + outb(0x64, 0x20); + uint8_t keyboard_status = (inb(0x60) | 1) & ~0x10; + outb(0x64, 0x60); + outb(0x60, keyboard_status); + outb(0x60, 0xF4); +} + +bool caps_on = false; +bool shift_on = false; + +void readline(int max, char* buffer) { + int index = 0; + + + uint8_t scancode = current_scancode; + while (scancode != 0x1c || index == 0) { + while (scancode == current_scancode); + scancode = current_scancode; + + char decoded = 0; + + if ((scancode&0x7f) == 0x2a) + shift_on = !(scancode&0x80); + + if (scancode == 0x0e && index > 0) { + set_curpos_raw(get_curpos()-1); + non_moving_put(' '); + index--; + } + + if (!shift_on) + decoded = key_to_char[scancode&0x7f]; + else + decoded = key_to_char_shift[scancode&0x7f]; + + if (decoded && scancode < 0x80) { + buffer[index++] = decoded; + printf("%c", decoded); + } + } + printf("\n"); +} \ No newline at end of file diff --git a/keyboard.h b/keyboard.h new file mode 100644 index 0000000..4318016 --- /dev/null +++ b/keyboard.h @@ -0,0 +1,12 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#include +#include "io.h" +#include "screenstuff.h" +#include "idt.h" + +void init_keyboard(); +void readline(int max, char* buffer); + +#endif \ No newline at end of file