Add keyboard callbacks, with a default for writing to the screen.

This commit is contained in:
Curle 2021-06-16 17:24:46 +01:00
parent 9bac0669a3
commit 439e1d9040
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
4 changed files with 123 additions and 53 deletions

View File

@ -0,0 +1,20 @@
#include <kernel/chroma.h>
/************************
*** Team Kitty, 2020 ***
*** Chroma ***
***********************/
typedef struct {
char Char;
int Scancode;
bool Pressed;
} KeyboardData;
typedef void (*KeyboardCallback)(KeyboardData* Frame);
extern KeyboardCallback KeyboardCallbacks[16];
int SetupKBCallback(void (*Handler)(KeyboardData* Frame));
void UninstallKBCallback(int Index);

View File

@ -1,5 +1,7 @@
#include <kernel/chroma.h>
//#include <kernel/system/screen.h>
#include <kernel/video/draw.h>
#include <kernel/system/driver/keyboard.h>
#include <editor/main.h>
/************************
*** Team Kitty, 2020 ***
@ -11,13 +13,15 @@
* If a function isn't fired here, directly or indirectly, it is not run.
*/
static bool KernelLoaded = false;
size_t KernelAddr = (size_t) &LoadAddr;
size_t KernelEnd = (size_t) &end;
address_space_t KernelAddressSpace;
void PrintPressedChar(KeyboardData* data);
int Main(void) {
KernelAddressSpace = (address_space_t) {0};
@ -38,25 +42,63 @@ int Main(void) {
InitPrint();
WriteStringWithFont("Initty Testing");
PrepareCPU();
PCIEnumerate();
InitMemoryManager();
//DrawSplash();
InitPrint();
InitPaging();
Printf("Paging complete. System initialized.\r\n");
Printf("Paging complete. System initialized.\n\r");
KernelLoaded = true;
SetForegroundColor(0x00FF0000);
WriteChar('C');
SetForegroundColor(0x0000FF00);
WriteChar('h');
SetForegroundColor(0x000000FF);
WriteChar('r');
SetForegroundColor(0x00FFFF00);
WriteChar('o');
SetForegroundColor(0x00FF00FF);
WriteChar('m');
SetForegroundColor(0x0000FFFF);
WriteChar('a');
WriteChar(' ');
SetForegroundColor(0x00FFFFFF);
WriteChar('T');
SetForegroundColor(0x0000AAAA);
WriteChar('i');
SetForegroundColor(0x00BBBBBB);
WriteChar('m');
SetForegroundColor(0x001E2D42);
WriteChar('e');
SetForegroundColor(0x00E0A969);
WriteChar('!');
WriteChar('\n');
SetForegroundColor(0x00FFFFFF);
int CharPrinterCallbackID = SetupKBCallback(&PrintPressedChar);
UNUSED(CharPrinterCallbackID);
for (;;) {}
return 0;
}
void PrintPressedChar(KeyboardData* data) {
if(!KernelLoaded) return;
if(data->Pressed) {
SerialPrintf("Key released: [\\%c]\r\n", data->Char);
} else {
SerialPrintf("Key pressed: [\\%c (%x)]\r\n", data->Char, data->Scancode);
Printf("%c", data->Char);
}
}
void SomethingWentWrong(const char* Message) {

View File

@ -1,4 +1,5 @@
#include <kernel/chroma.h>
#include <kernel/system/driver/keyboard.h>
/************************
*** Team Kitty, 2020 ***
@ -6,10 +7,10 @@
***********************/
/* This file contains (mostly unused) implementations of a full PS/2 keyboard driver.
*
*
* It provides provisions for full 2-way communication, as well as auxiliary key commands.
* //TODO: Media keys?
*
*
* Once this driver is to a workable state, I would like to start adding a proper keyboard buffer,
* which will integrate with a window system.
*
@ -19,14 +20,14 @@ char keys[128] = {
0, 27,
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
0,
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '#',
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, 0, 0, 0, 0, 0, 0, 0,
0,
0,
0,
@ -49,7 +50,22 @@ char keys[128] = {
0,
};
KeyboardCallback KeyboardCallbacks[16] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static int CurrentCallback = 0;
int SetupKBCallback(void (*Handler)(KeyboardData* Frame)) {
KeyboardCallbacks[CurrentCallback++] = Handler;
return CurrentCallback;
}
void UninstallKBCallback(int Number) {
KeyboardCallbacks[Number] = NULL; // 0 is used in the common check to make sure that the function is callable.
// This removes this callback from that check, ergo the function will no longer be called.
}
void KbdEcho() {
if(!KbdFlags.EchoCount) {
@ -101,15 +117,20 @@ void UpdateKeyboard(uint8_t msg) {
break;
}
KeyboardData data = (KeyboardData) {
.Scancode = msg,
.Pressed = msg > 0x80 && msg < 0xD8 ? true : false,
.Char = msg > 0x80 && msg < 0xD8 ? keys[msg - 0x80] : keys[msg]
};
void (*Handler)(KeyboardData* data);
if(msg & 0x80) {
} else {
SerialPrintf("Key pressed: [\\%c]\r\n", keys[msg]);
WriteChar(keys[msg]);
for(size_t handlerNum = 0; handlerNum < 16; handlerNum++) {
Handler = KeyboardCallbacks[handlerNum];
if(Handler) {
Handler(&data);
}
}
}
void Send8042(size_t info) {

View File

@ -8,16 +8,16 @@
*
* As they use the GCC interrupt attribute,
* this file must be compiled without red-
* zone protection, thus all of these
* zone protection, thus all of these
* functions are in their own file to
* accomodate this.
*
*
* Additionally, the kernel now has SSE/AVX support.
* So this file and this file *alone* must be compiled with
* -mgeneral-regs-only
*
*
* Calling a function like so:
*
*
* __attribute__((interrupt)) isr1(registers_t* frame) {}
*
* allows the function to be used to serve
@ -33,16 +33,15 @@
*/
#include <kernel/chroma.h>
#include <kernel/video/draw.h>
#include <kernel/system/interrupts.h>
#include <stdbool.h>
#define UNUSED(X) ((void)X)
const char* ExceptionStrings[] = {
"Division by Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Breakpoint",
"Into Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
@ -93,13 +92,10 @@ void ISR_Common(INTERRUPT_FRAME* Frame, size_t Exception) {
/* Only the first 32 ISR/IRQs are reserved for exceptions by the CPU. We can handle up to 512 interrupts total, though. */
if(Exception < 32) {
FillScreen(0x0000FF00);
SetForegroundColor(0x0000FF00);
FillScreen();
/* ExceptionStrings is an array of c-strings defined in kernel.h */
SerialPrintf("[ ISR] %s exception!\r\n", ExceptionStrings[Exception]);
//printf("%s exception!", ExceptionStrings[Exception]);
//panic();
}
}
@ -110,16 +106,11 @@ void ISR_Error_Common(INTERRUPT_FRAME* Frame, size_t ErrorCode, size_t Exception
UNUSED(Frame);
if(Exception < 32) {
FillScreen(0x0000FF00);
SetForegroundColor(0x0000FF00);
FillScreen();
SerialPrintf("[ ISR] ISR Error %d raised, EC %d!\r\n", Exception, ErrorCode);
SerialPrintf("[ ISR] %s exception!\r\n", ExceptionStrings[Exception]);
while(true) {}
//serialPrint(ExceptionStrings[Exception]);
//serialPrintf(" Exception. Context given: %d\r\n", Frame->ErrorCode);
//printf("%s exception. Context: %x", ExceptionStrings[Exception], Frame->ErrorCode);
//panic();
}
@ -131,10 +122,6 @@ void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interrupt) {
// First we need to define a function pointer..
void (*Handler)(INTERRUPT_FRAME* Frame);
// Tell the user we've got an interrupt in..
//serial_print(0x3F8, "[INFO] Received IRQ: " + interrupt);
//printf("[INFO] Received IRQ: %x", Interrupt);
/* We set all uninitialized routines to 0, so the if(handler) check here allows us to
safely tell whether we've actually got something for this IRQ. */
Handler = IRQ_Handlers[Interrupt];
@ -147,7 +134,7 @@ void IRQ_Common(INTERRUPT_FRAME* Frame, size_t Interrupt) {
/* The Slave PIC must be told it's been read in order to receive another 8+ IRQ. */
if(Interrupt > 7)
WritePort(0xA0, 0x20, 1);
/* In either case, we tell the Master PIC it's been read to receive any IRQ. */
WritePort(0x20, 0x20, 1);
@ -186,52 +173,52 @@ void EmptyIRQ(INTERRUPT_FRAME* frame) {
UNUSED(frame);
// Flash the borders green, then back to blue
SetForegroundColor(0x0000FF00);
for(size_t y = 0; y < bootldr.fb_height; y++) {
for(size_t x = 0; x < 20; x++) {
DrawPixel(x, y, 0x0000FF00);
DrawPixel(x, y);
}
for(size_t x = (bootldr.fb_width - 20); x < bootldr.fb_width; x++) {
DrawPixel(x, y, 0x0000FF00);
DrawPixel(x, y);
}
}
for(size_t x = 0; x < bootldr.fb_width; x++) {
for(size_t y = 0; y < 20; y++) {
DrawPixel(x, y, 0x0000FF00);
DrawPixel(x, y);
}
for(size_t y = (bootldr.fb_height - 20); y < bootldr.fb_height; y++) {
DrawPixel(x, y, 0x0000FF00);
DrawPixel(x, y);
}
}
for(size_t i = 0; i < 100000; i++) {}
SetForegroundColor(0x000000FF);
for(size_t y = 0; y < bootldr.fb_height; y++) {
for(size_t x = 0; x < 20; x++) {
DrawPixel(x, y, 0x000000FF);
DrawPixel(x, y);
}
for(size_t x = (bootldr.fb_width - 20); x < bootldr.fb_width; x++) {
DrawPixel(x, y, 0x000000FF);
DrawPixel(x, y);
}
}
for(size_t x = 0; x < bootldr.fb_width; x++) {
for(size_t y = 0; y < 20; y++) {
DrawPixel(x, y, 0x000000FF);
DrawPixel(x, y);
}
for(size_t y = (bootldr.fb_height - 20); y < bootldr.fb_height; y++) {
DrawPixel(x, y, 0x000000FF);
DrawPixel(x, y);
}
}
}
static void KeyboardCallback(INTERRUPT_FRAME* frame) {
UNUSED(frame);
uint8_t msg = ReadPort(0x60, 1);