Add keyboard callbacks, with a default for writing to the screen.
This commit is contained in:
parent
9bac0669a3
commit
439e1d9040
20
inc/kernel/system/driver/keyboard.h
Normal file
20
inc/kernel/system/driver/keyboard.h
Normal 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);
|
54
src/kernel.c
54
src/kernel.c
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user