forked from PoliEcho-holding-org/kern
Improved keyboard IRQ handler, added getc() function, improved read()
This commit is contained in:
+40
-70
@@ -3,95 +3,65 @@
|
||||
|
||||
#include <interrupt/idt.h>
|
||||
#include <interrupt/pic.h>
|
||||
#include <ports/io.h>
|
||||
#include <screen/text.h>
|
||||
#include <stdint.h>
|
||||
#include <keyboard/keys.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// Keycodes
|
||||
#define LEFT_SHIFT_PRESS 0x2a
|
||||
#define LEFT_SHIFT_RELEASE (LEFT_SHIFT_PRESS | 0x80)
|
||||
#define RIGHT_SHIFT_PRESS 0x36
|
||||
#define RIGHT_SHIFT_RELEASE (RIGHT_SHIFT_PRESS | 0x80)
|
||||
#define LEFT_CTRL_PRESS 0x1D
|
||||
#define LEFT_CTRL_RELEASE (LEFT_CTRL_PRESS | 0x80)
|
||||
#define RIGHT_CTRL_PRESS 0x1D
|
||||
#define RIGHT_CTRL_RELEASE (RIGHT_CTRL_PRESS | 0x80)
|
||||
#define LEFT_ALT_PRESS 0x38
|
||||
#define LEFT_ALT_RELEASE (LEFT_ALT_PRESS | 0x80)
|
||||
#define RIGHT_ALT_PRESS 0x38
|
||||
#define RIGHT_ALT_RELEASE (RIGHT_ALT_PRESS | 0x80)
|
||||
#define MAX_INPUT_LENGTH 256
|
||||
|
||||
#define MAX_BUFFER_SIZE 256
|
||||
typedef struct {
|
||||
char character;
|
||||
uint8_t shift;
|
||||
} keyboardState_t;
|
||||
|
||||
const char US_Keyboard[2][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, '\\', '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,
|
||||
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', // Numpad
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
},
|
||||
{
|
||||
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t',
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 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, '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
|
||||
}
|
||||
};
|
||||
// TODO: Put at set address
|
||||
keyboardState_t keyboard;
|
||||
|
||||
uint8_t shift = 0;
|
||||
|
||||
uint16_t bufferLen = 0;
|
||||
char buffer[MAX_BUFFER_SIZE + 1] = { 0 };
|
||||
bool echo = false;
|
||||
bool canBackspace = false;
|
||||
|
||||
// TODO: Refactor this
|
||||
__attribute__ ((interrupt))
|
||||
void keyboardHandler(intFrame_t* iframe) {
|
||||
uint8_t scancode;
|
||||
scancode = inb(0x60);
|
||||
uint8_t scancode = inb(0x60);
|
||||
char c = US_Keyboard[keyboard.shift][scancode];
|
||||
|
||||
if (scancode == LEFT_SHIFT_PRESS || scancode == RIGHT_SHIFT_PRESS) shift = 1;
|
||||
else if (scancode == LEFT_SHIFT_RELEASE || scancode == RIGHT_SHIFT_RELEASE) shift = 0;
|
||||
|
||||
char c = US_Keyboard[shift][scancode];
|
||||
if (scancode == LEFT_SHIFT_PRESS || scancode == RIGHT_SHIFT_PRESS) {
|
||||
keyboard.shift = 1;
|
||||
} else if (scancode == LEFT_SHIFT_RELEASE || scancode == RIGHT_SHIFT_RELEASE) {
|
||||
keyboard.shift = 0;
|
||||
}
|
||||
|
||||
if (scancode & 0x80) { // Keyup
|
||||
} else if (c != 0) {
|
||||
if (!canBackspace && c == '\b') return;
|
||||
if (echo) putc(c);
|
||||
|
||||
buffer[bufferLen] = c;
|
||||
|
||||
if (c == '\b') bufferLen--;
|
||||
else bufferLen++;
|
||||
|
||||
if (bufferLen > 0) canBackspace = true;
|
||||
else canBackspace = false;
|
||||
} else if (c != '\0') {
|
||||
keyboard.character = c;
|
||||
}
|
||||
|
||||
sendPicEOI(1);
|
||||
}
|
||||
|
||||
// TODO: Add a 'char readc();' function that returns a single read character and use it for read()
|
||||
// Also this should be refactored to not use so many flag variables
|
||||
char* read(char terminator) {
|
||||
bufferLen = 0;
|
||||
echo = true;
|
||||
char getc() {
|
||||
keyboard.character = '\0';
|
||||
while (keyboard.character == '\0') __asm__ volatile ("hlt");
|
||||
return keyboard.character;
|
||||
}
|
||||
|
||||
while (buffer[bufferLen-1] != terminator && bufferLen < MAX_BUFFER_SIZE);
|
||||
// Reads until a newline
|
||||
char inputBuffer[MAX_INPUT_LENGTH];
|
||||
char* read() {
|
||||
char c;
|
||||
uint8_t len = 0;
|
||||
|
||||
echo = false;
|
||||
canBackspace = false;
|
||||
buffer[bufferLen] = '\0';
|
||||
while ((c = getc()) != '\n') {
|
||||
if (c == '\b' && len > 0) {
|
||||
len--;
|
||||
putc(c);
|
||||
} else if (len + 1 != MAX_INPUT_LENGTH) { // Check if we can add a new character
|
||||
inputBuffer[len++] = c;
|
||||
putc(c);
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
inputBuffer[len++] = c; // Add newline
|
||||
putc(c);
|
||||
inputBuffer[len] = '\0'; // Null terminate
|
||||
return inputBuffer;
|
||||
}
|
||||
|
||||
void setupKeyboard() {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef KEYS_H
|
||||
#define KEYS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LEFT_SHIFT_PRESS 0x2a
|
||||
#define LEFT_SHIFT_RELEASE (LEFT_SHIFT_PRESS | 0x80)
|
||||
#define RIGHT_SHIFT_PRESS 0x36
|
||||
#define RIGHT_SHIFT_RELEASE (RIGHT_SHIFT_PRESS | 0x80)
|
||||
#define LEFT_CTRL_PRESS 0x1D
|
||||
#define LEFT_CTRL_RELEASE (LEFT_CTRL_PRESS | 0x80)
|
||||
#define RIGHT_CTRL_PRESS 0x1D
|
||||
#define RIGHT_CTRL_RELEASE (RIGHT_CTRL_PRESS | 0x80)
|
||||
#define LEFT_ALT_PRESS 0x38
|
||||
#define LEFT_ALT_RELEASE (LEFT_ALT_PRESS | 0x80)
|
||||
#define RIGHT_ALT_PRESS 0x38
|
||||
#define RIGHT_ALT_RELEASE (RIGHT_ALT_PRESS | 0x80)
|
||||
|
||||
// Basic US Keyboard layout
|
||||
static const char US_Keyboard[2][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, '\\','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,
|
||||
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.', // Numpad
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
},
|
||||
{
|
||||
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t',
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 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, '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
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
+2
-2
@@ -64,7 +64,7 @@ void main() {
|
||||
// TODO: Make it in another file
|
||||
while (1) {
|
||||
print(PROMPT);
|
||||
char* input = read('\n');
|
||||
char* input = read();
|
||||
|
||||
if (input[0] == '\n') continue;
|
||||
|
||||
@@ -169,7 +169,7 @@ void main() {
|
||||
drawCircle(1500, 600, 300, WHITE);
|
||||
fillCircle(950, 750, 75, rgb(0xa2, 0xd6, 0xf9));
|
||||
|
||||
read('q'); // Wait until we get a 'q'
|
||||
getc(); // Wait until we get a 'q'
|
||||
clear();
|
||||
} else if (strcmp(input, "help") == 0) {
|
||||
print("Available Commands:\n");
|
||||
|
||||
@@ -36,13 +36,13 @@ Legend:
|
||||
- [x] Rectange :)
|
||||
- [x] Circle!
|
||||
- [x] Filled verisons
|
||||
- [ ] Interrupts
|
||||
- [x] Interrupts
|
||||
- [x] IDT Setup (idt.h)
|
||||
- [x] Exception handling
|
||||
- [x] Hardware/software interrupts
|
||||
- [x] Syscalls! (int 0x80)
|
||||
- [x] IRQ 0 - PIT
|
||||
- [ ] IRQ 1 - Keyboard
|
||||
- [x] IRQ 1 - Keyboard
|
||||
- [x] IRQ 8 - CMOS Real time clock
|
||||
- [?] Other IRQs (idk which ones)
|
||||
- [ ] Math
|
||||
|
||||
Reference in New Issue
Block a user