Implemented simple IO for getting keyboard input.
This commit is contained in:
parent
d711938821
commit
f4bad14fcd
@ -25,7 +25,7 @@ public:
|
||||
using iterator = pointer;
|
||||
using const_iterator = const_pointer;
|
||||
|
||||
T _elements[N];
|
||||
T _elements[N] = {};
|
||||
|
||||
constexpr reference operator[](size_type pos) noexcept
|
||||
{
|
||||
|
@ -8,10 +8,19 @@
|
||||
|
||||
namespace std
|
||||
{
|
||||
using ::EOF;
|
||||
|
||||
using ::putchar;
|
||||
using ::puts;
|
||||
using ::printf;
|
||||
using ::vprintf;
|
||||
using ::snprintf;
|
||||
using ::vsnprintf;
|
||||
|
||||
using ::fgets;
|
||||
using ::fgetc;
|
||||
using ::getc;
|
||||
using ::getchar;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CSTDIO_INCLUDED)
|
||||
|
@ -4,6 +4,7 @@
|
||||
#if !defined(BAD_APPLE_OS_DRIVERS_PS2_HPP_INCLUDED)
|
||||
#define BAD_APPLE_OS_DRIVERS_PS2_HPP_INCLUDED
|
||||
|
||||
#include <array>
|
||||
#include "drivers/pic.hpp"
|
||||
|
||||
namespace baos::ps2
|
||||
@ -77,6 +78,7 @@ enum class Scancode
|
||||
ENTER = 0x5A,
|
||||
BRACKET_CLOSE = 0x5B,
|
||||
BACKSLASH = 0x5D,
|
||||
GRAVE = 0x61,
|
||||
BACKSPACE = 0x66,
|
||||
KP_1 = 0x69,
|
||||
KP_4 = 0x6B,
|
||||
@ -98,46 +100,61 @@ enum class Scancode
|
||||
SCROLLOCK = 0x7E,
|
||||
F7 = 0x83,
|
||||
|
||||
MM_WWW_SEARCH = 0xE010,
|
||||
RIGHT_ALT = 0xE011,
|
||||
RIGHT_CONTROL = 0xE014,
|
||||
MM_PREV_TRACK = 0xE015,
|
||||
LEFT_GUI = 0xE01F,
|
||||
MM_WWW_FAVORITES = 0xE020,
|
||||
MM_VOLUME_DOWN = 0xE021,
|
||||
MM_MUTE = 0xE023,
|
||||
RIGHT_GUI = 0xE027,
|
||||
MM_WWW_STOP = 0xE028,
|
||||
MM_CALCULATOR = 0xE02B,
|
||||
APPS = 0xE02F,
|
||||
MM_WWW_FORWARD = 0xE030,
|
||||
MM_VOLUME_UP = 0xE032,
|
||||
MM_PLAY_PAUSE = 0xE034,
|
||||
ACPI_POWER = 0xE037,
|
||||
MM_WWW_BACK = 0xE038,
|
||||
MM_WWW_HOME = 0xE03A,
|
||||
MM_STOP = 0xE03B,
|
||||
ACPI_SLEEP = 0xE03F,
|
||||
MM_MY_COMPUTER = 0xE040,
|
||||
MM_EMAIL = 0xE048,
|
||||
KP_SLASH = 0xE04A,
|
||||
MM_NEXT_TRACK = 0xE04D,
|
||||
MM_MEDIA_SELECT = 0xE050,
|
||||
KP_ENTER = 0xE05A,
|
||||
ACPI_WAKE = 0xE05E,
|
||||
END = 0xE069,
|
||||
ARROW_LEFT = 0xE06B,
|
||||
HOME = 0xE06C,
|
||||
INSERT = 0xE070,
|
||||
DELETE = 0xE071,
|
||||
ARROW_DOWN = 0xE072,
|
||||
ARROW_RIGHT = 0xE074,
|
||||
ARROW_UP = 0xE075,
|
||||
PAGE_DOWN = 0xE07A,
|
||||
PAGE_UP = 0xE07D,
|
||||
MM_WWW_SEARCH = 0x0110,
|
||||
RIGHT_ALT = 0x0111,
|
||||
RIGHT_CONTROL = 0x0114,
|
||||
MM_PREV_TRACK = 0x0115,
|
||||
LEFT_GUI = 0x011F,
|
||||
MM_WWW_FAVORITES = 0x0120,
|
||||
MM_VOLUME_DOWN = 0x0121,
|
||||
MM_MUTE = 0x0123,
|
||||
RIGHT_GUI = 0x0127,
|
||||
MM_WWW_STOP = 0x0128,
|
||||
MM_CALCULATOR = 0x012B,
|
||||
APPS = 0x012F,
|
||||
MM_WWW_FORWARD = 0x0130,
|
||||
MM_VOLUME_UP = 0x0132,
|
||||
MM_PLAY_PAUSE = 0x0134,
|
||||
ACPI_POWER = 0x0137,
|
||||
MM_WWW_BACK = 0x0138,
|
||||
MM_WWW_HOME = 0x013A,
|
||||
MM_STOP = 0x013B,
|
||||
ACPI_SLEEP = 0x013F,
|
||||
MM_MY_COMPUTER = 0x0140,
|
||||
MM_EMAIL = 0x0148,
|
||||
KP_SLASH = 0x014A,
|
||||
MM_NEXT_TRACK = 0x014D,
|
||||
MM_MEDIA_SELECT = 0x0150,
|
||||
KP_ENTER = 0x015A,
|
||||
ACPI_WAKE = 0x015E,
|
||||
END = 0x0169,
|
||||
ARROW_LEFT = 0x016B,
|
||||
HOME = 0x016C,
|
||||
INSERT = 0x0170,
|
||||
DELETE = 0x0171,
|
||||
ARROW_DOWN = 0x0172,
|
||||
ARROW_RIGHT = 0x0174,
|
||||
ARROW_UP = 0x0175,
|
||||
PAGE_DOWN = 0x017A,
|
||||
PAGE_UP = 0x017D,
|
||||
|
||||
PRINT_SCREEN = 0xF000,
|
||||
PAUSE = 0xF001
|
||||
PRINT_SCREEN = 0x017E,
|
||||
PAUSE = 0x017F
|
||||
};
|
||||
inline constexpr std::uint16_t MAX_SCANCODE = static_cast<std::uint16_t>(Scancode::PAUSE) + 1;
|
||||
|
||||
struct Keymap
|
||||
{
|
||||
std::array<char, MAX_SCANCODE> regularKeys;
|
||||
std::array<char, MAX_SCANCODE> shiftedKeys;
|
||||
std::array<char, MAX_SCANCODE> altGredKeys;
|
||||
|
||||
constexpr void set(Scancode scancode, char regular, char shifted = '\0', char altgred = '\0') noexcept
|
||||
{
|
||||
regularKeys[static_cast<unsigned>(scancode)] = regular;
|
||||
shiftedKeys[static_cast<unsigned>(scancode)] = shifted;
|
||||
altGredKeys[static_cast<unsigned>(scancode)] = altgred;
|
||||
}
|
||||
};
|
||||
|
||||
struct KeyEvent
|
||||
@ -152,8 +169,11 @@ struct KeyEvent
|
||||
__attribute__((interrupt))
|
||||
void isrKeyboard(InterruptFrame* interruptFrame) noexcept;
|
||||
|
||||
[[nodiscard]] bool isKeyDown(Scancode scancode) noexcept;
|
||||
[[nodiscard]] bool readKey(KeyEvent& outEvent) noexcept;
|
||||
[[nodiscard]] bool readChar(char& outChar) noexcept;
|
||||
[[nodiscard]] const char* keyName(Scancode scancode) noexcept;
|
||||
[[nodiscard]] bool keyToChar(Scancode scancode, char& outChar) noexcept;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_DRIVERS_PS2_HPP_INCLUDED)
|
||||
|
44
targets/_any/include/os/tools/ringbuffer.hpp
Normal file
44
targets/_any/include/os/tools/ringbuffer.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_OS_TOOLS_RINGBUFFER_HPP_INCLUDED)
|
||||
#define BAD_APPLE_OS_OS_TOOLS_RINGBUFFER_HPP_INCLUDED
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
namespace baos
|
||||
{
|
||||
template<typename T, std::size_t SIZE>
|
||||
class RingBuffer
|
||||
{
|
||||
private:
|
||||
std::array<T, SIZE> mElements;
|
||||
std::size_t mBufferedElements = 0;
|
||||
std::size_t mPosition = 0;
|
||||
public:
|
||||
[[nodiscard]] bool full() const noexcept { return mBufferedElements == SIZE; }
|
||||
[[nodiscard]] bool empty() const noexcept { return mBufferedElements == 0; }
|
||||
bool append(T element) noexcept
|
||||
{
|
||||
if (full()) {
|
||||
return false;
|
||||
}
|
||||
mElements[mPosition] = std::move(element);
|
||||
++mBufferedElements;
|
||||
mPosition = (mPosition + 1) % SIZE;
|
||||
return true;
|
||||
}
|
||||
bool next(T& outElement) noexcept
|
||||
{
|
||||
if (empty()) {
|
||||
return false;
|
||||
}
|
||||
outElement = std::move(mElements[(mPosition + SIZE - mBufferedElements) % SIZE]);
|
||||
--mBufferedElements;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_OS_TOOLS_RINGBUFFER_HPP_INCLUDED)
|
@ -8,8 +8,16 @@
|
||||
#include <stddef.h>
|
||||
#include "./detail/common.h"
|
||||
|
||||
#define stdin __stdin
|
||||
|
||||
BA_EXTERN_C_BEGIN
|
||||
|
||||
typedef struct __file FILE;
|
||||
|
||||
extern FILE* __stdin;
|
||||
|
||||
static int EOF = -1;
|
||||
|
||||
int putchar(int chr) BA_CXX_NOEXCEPT;
|
||||
int puts(const char* str) BA_CXX_NOEXCEPT;
|
||||
int printf(const char* format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 1, 2)));
|
||||
@ -17,6 +25,11 @@ int vprintf(const char* format, va_list vlist) BA_CXX_NOEXCEPT;
|
||||
int snprintf(char* buffer, size_t bufferSize, const char* format, ...) BA_CXX_NOEXCEPT __attribute__((format(printf, 3, 4)));
|
||||
int vsnprintf(char* buffer, size_t bufferSize, const char* format, va_list vlist) BA_CXX_NOEXCEPT;
|
||||
|
||||
int fgetc(FILE* stream) BA_CXX_NOEXCEPT;
|
||||
char* fgets(char* buffer, int count, FILE* stream) BA_CXX_NOEXCEPT;
|
||||
inline int getc(FILE* stream) BA_CXX_NOEXCEPT { return fgetc(stream); }
|
||||
inline int getchar() BA_CXX_NOEXCEPT { return fgetc(stdin); }
|
||||
|
||||
BA_EXTERN_C_END
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_STDIO_H_INCLUDED)
|
||||
|
@ -1,6 +1,16 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
extern "C" void main()
|
||||
{
|
||||
|
||||
// __asm__ __volatile__("cli");
|
||||
while(true);
|
||||
while(true)
|
||||
{
|
||||
int chr = std::getchar();
|
||||
if (chr != std::EOF)
|
||||
{
|
||||
putchar(chr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,37 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <stdarg.h>
|
||||
#include "drivers/ps2.hpp"
|
||||
#include "os/serial.hpp"
|
||||
#include "os/tty.hpp"
|
||||
#include "os/tools/printf_helper.hpp"
|
||||
#include "os/tools/ringbuffer.hpp"
|
||||
|
||||
struct __file
|
||||
{
|
||||
protected:
|
||||
static constexpr unsigned BUFFER_SIZE = 4096;
|
||||
|
||||
baos::RingBuffer<char, BUFFER_SIZE> mBuffer;
|
||||
bool mEof = false;
|
||||
bool mError = false;
|
||||
protected:
|
||||
virtual bool underflow() noexcept = 0;
|
||||
public:
|
||||
[[nodiscard]] bool isEof() const noexcept { return mEof; }
|
||||
[[nodiscard]] bool isError() const noexcept { return mError; }
|
||||
|
||||
bool readChar(char& outChar) noexcept
|
||||
{
|
||||
while (!mBuffer.next(outChar)) {
|
||||
if (!underflow()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -34,10 +58,33 @@ struct BufferPrinter
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class StdinFile : public __file
|
||||
{
|
||||
public:
|
||||
bool underflow() noexcept override
|
||||
{
|
||||
while (mBuffer.empty())
|
||||
{
|
||||
char chr;
|
||||
while (!mBuffer.full() && baos::ps2::readChar(chr))
|
||||
{
|
||||
mBuffer.append(chr);
|
||||
if (chr == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
StdinFile gStdin;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
FILE* __stdin = &gStdin;
|
||||
|
||||
int putchar(int chr) noexcept
|
||||
{
|
||||
tty::putChar(static_cast<char>(chr));
|
||||
@ -100,5 +147,42 @@ int vsnprintf(char* buffer, size_t bufferSize, const char* format, va_list vlist
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
int fgetc(FILE* stream) noexcept
|
||||
{
|
||||
char chr;
|
||||
if (!stream->readChar(chr))
|
||||
{
|
||||
return EOF;
|
||||
}
|
||||
return chr;
|
||||
}
|
||||
|
||||
char* fgets(char* buffer, int count, FILE* stream) noexcept
|
||||
{
|
||||
if (count < 1) {
|
||||
return nullptr;
|
||||
}
|
||||
if (count == 1)
|
||||
{
|
||||
*buffer = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
for (; pos < count - 1; ++pos)
|
||||
{
|
||||
if (!stream->readChar(buffer[pos]))
|
||||
{
|
||||
if (stream->isError() || pos == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
buffer[pos] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
|
@ -1,12 +1,296 @@
|
||||
|
||||
#include "drivers/ps2.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include "drivers/pic.hpp"
|
||||
#include "os/port.hpp"
|
||||
|
||||
namespace baos::ps2
|
||||
{
|
||||
namespace
|
||||
{
|
||||
// <editor-fold desc="KEYMAP_EN_US">
|
||||
const constinit Keymap KEYMAP_EN_US = []()
|
||||
{
|
||||
Keymap keymap = {};
|
||||
keymap.set(Scancode::BACKTICK, '`', '~');
|
||||
keymap.set(Scancode::_0, '0', ')');
|
||||
keymap.set(Scancode::_1, '1', '!');
|
||||
keymap.set(Scancode::_2, '2', '@');
|
||||
keymap.set(Scancode::_3, '3', '#');
|
||||
keymap.set(Scancode::_4, '4', '$');
|
||||
keymap.set(Scancode::_5, '5', '%');
|
||||
keymap.set(Scancode::_6, '6', '^');
|
||||
keymap.set(Scancode::_7, '7', '&');
|
||||
keymap.set(Scancode::_8, '8', '*');
|
||||
keymap.set(Scancode::_9, '9', '(');
|
||||
keymap.set(Scancode::A, 'a', 'A');
|
||||
keymap.set(Scancode::B, 'b', 'B');
|
||||
keymap.set(Scancode::C, 'c', 'C');
|
||||
keymap.set(Scancode::D, 'd', 'D');
|
||||
keymap.set(Scancode::E, 'e', 'E');
|
||||
keymap.set(Scancode::F, 'f', 'F');
|
||||
keymap.set(Scancode::G, 'g', 'G');
|
||||
keymap.set(Scancode::H, 'h', 'H');
|
||||
keymap.set(Scancode::I, 'i', 'I');
|
||||
keymap.set(Scancode::J, 'j', 'J');
|
||||
keymap.set(Scancode::K, 'k', 'K');
|
||||
keymap.set(Scancode::L, 'l', 'L');
|
||||
keymap.set(Scancode::M, 'm', 'M');
|
||||
keymap.set(Scancode::N, 'n', 'N');
|
||||
keymap.set(Scancode::O, 'o', 'O');
|
||||
keymap.set(Scancode::P, 'p', 'P');
|
||||
keymap.set(Scancode::Q, 'q', 'Q');
|
||||
keymap.set(Scancode::R, 'r', 'R');
|
||||
keymap.set(Scancode::S, 's', 'S');
|
||||
keymap.set(Scancode::T, 't', 'T');
|
||||
keymap.set(Scancode::U, 'u', 'U');
|
||||
keymap.set(Scancode::V, 'v', 'V');
|
||||
keymap.set(Scancode::W, 'w', 'W');
|
||||
keymap.set(Scancode::X, 'x', 'X');
|
||||
keymap.set(Scancode::Y, 'y', 'Y');
|
||||
keymap.set(Scancode::Z, 'z', 'Z');
|
||||
keymap.set(Scancode::ENTER, '\n');
|
||||
keymap.set(Scancode::MINUS, '-', '_');
|
||||
keymap.set(Scancode::EQUALS, '=', '+');
|
||||
keymap.set(Scancode::TAB, '\t');
|
||||
keymap.set(Scancode::BRACKET_OPEN, '[', '{');
|
||||
keymap.set(Scancode::BRACKET_CLOSE, ']', '}');
|
||||
keymap.set(Scancode::BACKSLASH, '\\', '|');
|
||||
keymap.set(Scancode::SEMICOLON, ';', ':');
|
||||
keymap.set(Scancode::APOSTROPHE, '\'', '"');
|
||||
keymap.set(Scancode::GRAVE, '`', '~');
|
||||
keymap.set(Scancode::COMMA, ',', '<');
|
||||
keymap.set(Scancode::DOT, '.', '>');
|
||||
keymap.set(Scancode::SLASH, '/', '?');
|
||||
|
||||
keymap.set(Scancode::KP_ENTER, '\n');
|
||||
keymap.set(Scancode::KP_0, '0');
|
||||
keymap.set(Scancode::KP_1, '1');
|
||||
keymap.set(Scancode::KP_2, '2');
|
||||
keymap.set(Scancode::KP_3, '3');
|
||||
keymap.set(Scancode::KP_4, '4');
|
||||
keymap.set(Scancode::KP_5, '5');
|
||||
keymap.set(Scancode::KP_6, '6');
|
||||
keymap.set(Scancode::KP_7, '7');
|
||||
keymap.set(Scancode::KP_8, '8');
|
||||
keymap.set(Scancode::KP_9, '9');
|
||||
keymap.set(Scancode::KP_SLASH, '/');
|
||||
keymap.set(Scancode::KP_ASTERISK, '*');
|
||||
keymap.set(Scancode::KP_MINUS, '-');
|
||||
keymap.set(Scancode::KP_PLUS, '+');
|
||||
return keymap;
|
||||
}();
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="KEYMAP_DE_DE">
|
||||
const constinit Keymap KEYMAP_DE_DE = []()
|
||||
{
|
||||
Keymap keymap = {};
|
||||
keymap.set(Scancode::BACKTICK, '^' /*'°'*/);
|
||||
keymap.set(Scancode::_0, '0', '=', '}');
|
||||
keymap.set(Scancode::_1, '1', '!');
|
||||
keymap.set(Scancode::_2, '2', '"');
|
||||
keymap.set(Scancode::_3, '3' /*'§'*/);
|
||||
keymap.set(Scancode::_4, '4', '$');
|
||||
keymap.set(Scancode::_5, '5', '%');
|
||||
keymap.set(Scancode::_6, '6', '&');
|
||||
keymap.set(Scancode::_7, '7', '/', '{');
|
||||
keymap.set(Scancode::_8, '8', '(', '[');
|
||||
keymap.set(Scancode::_9, '9', ')', ']');
|
||||
keymap.set(Scancode::A, 'a', 'A');
|
||||
keymap.set(Scancode::B, 'b', 'B');
|
||||
keymap.set(Scancode::C, 'c', 'C');
|
||||
keymap.set(Scancode::D, 'd', 'D');
|
||||
keymap.set(Scancode::E, 'e', 'E' /*, '€' */);
|
||||
keymap.set(Scancode::F, 'f', 'F');
|
||||
keymap.set(Scancode::G, 'g', 'G');
|
||||
keymap.set(Scancode::H, 'h', 'H');
|
||||
keymap.set(Scancode::I, 'i', 'I');
|
||||
keymap.set(Scancode::J, 'j', 'J');
|
||||
keymap.set(Scancode::K, 'k', 'K');
|
||||
keymap.set(Scancode::L, 'l', 'L');
|
||||
keymap.set(Scancode::M, 'm', 'M');
|
||||
keymap.set(Scancode::N, 'n', 'N');
|
||||
keymap.set(Scancode::O, 'o', 'O');
|
||||
keymap.set(Scancode::P, 'p', 'P');
|
||||
keymap.set(Scancode::Q, 'q', 'Q', '@');
|
||||
keymap.set(Scancode::R, 'r', 'R');
|
||||
keymap.set(Scancode::S, 's', 'S');
|
||||
keymap.set(Scancode::T, 't', 'T');
|
||||
keymap.set(Scancode::U, 'u', 'U');
|
||||
keymap.set(Scancode::V, 'v', 'V');
|
||||
keymap.set(Scancode::W, 'w', 'W');
|
||||
keymap.set(Scancode::X, 'x', 'X');
|
||||
keymap.set(Scancode::Y, 'y', 'Y');
|
||||
keymap.set(Scancode::Z, 'z', 'Z');
|
||||
keymap.set(Scancode::ENTER, '\n');
|
||||
keymap.set(Scancode::MINUS, '?' /* ß */, '?', '\\');
|
||||
keymap.set(Scancode::EQUALS, '`' /* ´ */, '`');
|
||||
keymap.set(Scancode::TAB, '\t');
|
||||
// keymap.set(Scancode::BRACKET_OPEN, 'ü', 'Ü');
|
||||
keymap.set(Scancode::BRACKET_CLOSE, '+', '*', '~');
|
||||
// keymap.set(Scancode::BACKSLASH, '\\', '|');
|
||||
// keymap.set(Scancode::SEMICOLON, 'ö', 'Ö');
|
||||
// keymap.set(Scancode::APOSTROPHE, 'ä', 'Ä');
|
||||
keymap.set(Scancode::GRAVE, '<', '>', '|');
|
||||
keymap.set(Scancode::COMMA, ',', ';');
|
||||
keymap.set(Scancode::DOT, '.', ':');
|
||||
keymap.set(Scancode::SLASH, '-', '_');
|
||||
|
||||
keymap.set(Scancode::KP_ENTER, '\n');
|
||||
keymap.set(Scancode::KP_0, '0');
|
||||
keymap.set(Scancode::KP_1, '1');
|
||||
keymap.set(Scancode::KP_2, '2');
|
||||
keymap.set(Scancode::KP_3, '3');
|
||||
keymap.set(Scancode::KP_4, '4');
|
||||
keymap.set(Scancode::KP_5, '5');
|
||||
keymap.set(Scancode::KP_6, '6');
|
||||
keymap.set(Scancode::KP_7, '7');
|
||||
keymap.set(Scancode::KP_8, '8');
|
||||
keymap.set(Scancode::KP_9, '9');
|
||||
keymap.set(Scancode::KP_SLASH, '/');
|
||||
keymap.set(Scancode::KP_ASTERISK, '*');
|
||||
keymap.set(Scancode::KP_MINUS, '-');
|
||||
keymap.set(Scancode::KP_PLUS, '+');
|
||||
return keymap;
|
||||
}();
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="SCANCODE_NAMES">
|
||||
const constinit std::array<const char*, MAX_SCANCODE> SCANCODE_NAMES = []()
|
||||
{
|
||||
std::array<const char*, MAX_SCANCODE> names;
|
||||
names.fill("INVALID");
|
||||
names[static_cast<unsigned>(Scancode::F9)] = "F9";
|
||||
names[static_cast<unsigned>(Scancode::F5)] = "F5";
|
||||
names[static_cast<unsigned>(Scancode::F3)] = "F3";
|
||||
names[static_cast<unsigned>(Scancode::F1)] = "F1";
|
||||
names[static_cast<unsigned>(Scancode::F2)] = "F2";
|
||||
names[static_cast<unsigned>(Scancode::F12)] = "F12";
|
||||
names[static_cast<unsigned>(Scancode::F10)] = "F10";
|
||||
names[static_cast<unsigned>(Scancode::F8)] = "F8";
|
||||
names[static_cast<unsigned>(Scancode::F6)] = "F6";
|
||||
names[static_cast<unsigned>(Scancode::F4)] = "F4";
|
||||
names[static_cast<unsigned>(Scancode::TAB)] = "TAB";
|
||||
names[static_cast<unsigned>(Scancode::BACKTICK)] = "BACKTICK";
|
||||
names[static_cast<unsigned>(Scancode::LEFT_ALT)] = "LEFT_ALT";
|
||||
names[static_cast<unsigned>(Scancode::LEFT_SHIFT)] = "LEFT_SHIFT";
|
||||
names[static_cast<unsigned>(Scancode::LEFT_CONTROL)] = "LEFT_CONTROL";
|
||||
names[static_cast<unsigned>(Scancode::Q)] = "Q";
|
||||
names[static_cast<unsigned>(Scancode::_1)] = "_1";
|
||||
names[static_cast<unsigned>(Scancode::Z)] = "Z";
|
||||
names[static_cast<unsigned>(Scancode::S)] = "S";
|
||||
names[static_cast<unsigned>(Scancode::A)] = "A";
|
||||
names[static_cast<unsigned>(Scancode::W)] = "W";
|
||||
names[static_cast<unsigned>(Scancode::_2)] = "_2";
|
||||
names[static_cast<unsigned>(Scancode::C)] = "C";
|
||||
names[static_cast<unsigned>(Scancode::X)] = "X";
|
||||
names[static_cast<unsigned>(Scancode::D)] = "D";
|
||||
names[static_cast<unsigned>(Scancode::E)] = "E";
|
||||
names[static_cast<unsigned>(Scancode::_4)] = "_4";
|
||||
names[static_cast<unsigned>(Scancode::_3)] = "_3";
|
||||
names[static_cast<unsigned>(Scancode::SPACE)] = "SPACE";
|
||||
names[static_cast<unsigned>(Scancode::V)] = "V";
|
||||
names[static_cast<unsigned>(Scancode::F)] = "F";
|
||||
names[static_cast<unsigned>(Scancode::T)] = "T";
|
||||
names[static_cast<unsigned>(Scancode::R)] = "R";
|
||||
names[static_cast<unsigned>(Scancode::_5)] = "_5";
|
||||
names[static_cast<unsigned>(Scancode::N)] = "N";
|
||||
names[static_cast<unsigned>(Scancode::B)] = "B";
|
||||
names[static_cast<unsigned>(Scancode::H)] = "H";
|
||||
names[static_cast<unsigned>(Scancode::G)] = "G";
|
||||
names[static_cast<unsigned>(Scancode::Y)] = "Y";
|
||||
names[static_cast<unsigned>(Scancode::_6)] = "_6";
|
||||
names[static_cast<unsigned>(Scancode::M)] = "M";
|
||||
names[static_cast<unsigned>(Scancode::J)] = "J";
|
||||
names[static_cast<unsigned>(Scancode::U)] = "U";
|
||||
names[static_cast<unsigned>(Scancode::_7)] = "_7";
|
||||
names[static_cast<unsigned>(Scancode::_8)] = "_8";
|
||||
names[static_cast<unsigned>(Scancode::COMMA)] = "COMMA";
|
||||
names[static_cast<unsigned>(Scancode::K)] = "K";
|
||||
names[static_cast<unsigned>(Scancode::I)] = "I";
|
||||
names[static_cast<unsigned>(Scancode::O)] = "O";
|
||||
names[static_cast<unsigned>(Scancode::_0)] = "_0";
|
||||
names[static_cast<unsigned>(Scancode::_9)] = "_9";
|
||||
names[static_cast<unsigned>(Scancode::DOT)] = "DOT";
|
||||
names[static_cast<unsigned>(Scancode::SLASH)] = "SLASH";
|
||||
names[static_cast<unsigned>(Scancode::L)] = "L";
|
||||
names[static_cast<unsigned>(Scancode::SEMICOLON)] = "SEMICOLON";
|
||||
names[static_cast<unsigned>(Scancode::P)] = "P";
|
||||
names[static_cast<unsigned>(Scancode::MINUS)] = "MINUS";
|
||||
names[static_cast<unsigned>(Scancode::APOSTROPHE)] = "APOSTROPHE";
|
||||
names[static_cast<unsigned>(Scancode::BRACKET_OPEN)] = "BRACKET_OPEN";
|
||||
names[static_cast<unsigned>(Scancode::EQUALS)] = "EQUALS";
|
||||
names[static_cast<unsigned>(Scancode::CAPSLOCK)] = "CAPSLOCK";
|
||||
names[static_cast<unsigned>(Scancode::RIGHT_SHIFT)] = "RIGHT_SHIFT";
|
||||
names[static_cast<unsigned>(Scancode::ENTER)] = "ENTER";
|
||||
names[static_cast<unsigned>(Scancode::BRACKET_CLOSE)] = "BRACKET_CLOSE";
|
||||
names[static_cast<unsigned>(Scancode::BACKSLASH)] = "BACKSLASH";
|
||||
names[static_cast<unsigned>(Scancode::GRAVE)] = "GRAVE";
|
||||
names[static_cast<unsigned>(Scancode::BACKSPACE)] = "BACKSPACE";
|
||||
names[static_cast<unsigned>(Scancode::KP_1)] = "KP_1";
|
||||
names[static_cast<unsigned>(Scancode::KP_4)] = "KP_4";
|
||||
names[static_cast<unsigned>(Scancode::KP_7)] = "KP_7";
|
||||
names[static_cast<unsigned>(Scancode::KP_0)] = "KP_0";
|
||||
names[static_cast<unsigned>(Scancode::KP_DOT)] = "KP_DOT";
|
||||
names[static_cast<unsigned>(Scancode::KP_2)] = "KP_2";
|
||||
names[static_cast<unsigned>(Scancode::KP_5)] = "KP_5";
|
||||
names[static_cast<unsigned>(Scancode::KP_6)] = "KP_6";
|
||||
names[static_cast<unsigned>(Scancode::KP_8)] = "KP_8";
|
||||
names[static_cast<unsigned>(Scancode::ESCAPE)] = "ESCAPE";
|
||||
names[static_cast<unsigned>(Scancode::NUMLOCK)] = "NUMLOCK";
|
||||
names[static_cast<unsigned>(Scancode::F11)] = "F11";
|
||||
names[static_cast<unsigned>(Scancode::KP_PLUS)] = "KP_PLUS";
|
||||
names[static_cast<unsigned>(Scancode::KP_3)] = "KP_3";
|
||||
names[static_cast<unsigned>(Scancode::KP_MINUS)] = "KP_MINUS";
|
||||
names[static_cast<unsigned>(Scancode::KP_ASTERISK)] = "KP_ASTERISK";
|
||||
names[static_cast<unsigned>(Scancode::KP_9)] = "KP_9";
|
||||
names[static_cast<unsigned>(Scancode::SCROLLOCK)] = "SCROLLOCK";
|
||||
names[static_cast<unsigned>(Scancode::F7)] = "F7";
|
||||
names[static_cast<unsigned>(Scancode::MM_WWW_SEARCH)] = "MM_WWW_SEARCH";
|
||||
names[static_cast<unsigned>(Scancode::RIGHT_ALT)] = "RIGHT_ALT";
|
||||
names[static_cast<unsigned>(Scancode::RIGHT_CONTROL)] = "RIGHT_CONTROL";
|
||||
names[static_cast<unsigned>(Scancode::MM_PREV_TRACK)] = "MM_PREV_TRACK";
|
||||
names[static_cast<unsigned>(Scancode::LEFT_GUI)] = "LEFT_GUI";
|
||||
names[static_cast<unsigned>(Scancode::MM_WWW_FAVORITES)] = "MM_WWW_FAVORITES";
|
||||
names[static_cast<unsigned>(Scancode::MM_VOLUME_DOWN)] = "MM_VOLUME_DOWN";
|
||||
names[static_cast<unsigned>(Scancode::MM_MUTE)] = "MM_MUTE";
|
||||
names[static_cast<unsigned>(Scancode::RIGHT_GUI)] = "RIGHT_GUI";
|
||||
names[static_cast<unsigned>(Scancode::MM_WWW_STOP)] = "MM_WWW_STOP";
|
||||
names[static_cast<unsigned>(Scancode::MM_CALCULATOR)] = "MM_CALCULATOR";
|
||||
names[static_cast<unsigned>(Scancode::APPS)] = "APPS";
|
||||
names[static_cast<unsigned>(Scancode::MM_WWW_FORWARD)] = "MM_WWW_FORWARD";
|
||||
names[static_cast<unsigned>(Scancode::MM_VOLUME_UP)] = "MM_VOLUME_UP";
|
||||
names[static_cast<unsigned>(Scancode::MM_PLAY_PAUSE)] = "MM_PLAY_PAUSE";
|
||||
names[static_cast<unsigned>(Scancode::ACPI_POWER)] = "ACPI_POWER";
|
||||
names[static_cast<unsigned>(Scancode::MM_WWW_BACK)] = "MM_WWW_BACK";
|
||||
names[static_cast<unsigned>(Scancode::MM_WWW_HOME)] = "MM_WWW_HOME";
|
||||
names[static_cast<unsigned>(Scancode::MM_STOP)] = "MM_STOP";
|
||||
names[static_cast<unsigned>(Scancode::ACPI_SLEEP)] = "ACPI_SLEEP";
|
||||
names[static_cast<unsigned>(Scancode::MM_MY_COMPUTER)] = "MM_MY_COMPUTER";
|
||||
names[static_cast<unsigned>(Scancode::MM_EMAIL)] = "MM_EMAIL";
|
||||
names[static_cast<unsigned>(Scancode::KP_SLASH)] = "KP_SLASH";
|
||||
names[static_cast<unsigned>(Scancode::MM_NEXT_TRACK)] = "MM_NEXT_TRACK";
|
||||
names[static_cast<unsigned>(Scancode::MM_MEDIA_SELECT)] = "MM_MEDIA_SELECT";
|
||||
names[static_cast<unsigned>(Scancode::KP_ENTER)] = "KP_ENTER";
|
||||
names[static_cast<unsigned>(Scancode::ACPI_WAKE)] = "ACPI_WAKE";
|
||||
names[static_cast<unsigned>(Scancode::END)] = "END";
|
||||
names[static_cast<unsigned>(Scancode::ARROW_LEFT)] = "ARROW_LEFT";
|
||||
names[static_cast<unsigned>(Scancode::HOME)] = "HOME";
|
||||
names[static_cast<unsigned>(Scancode::INSERT)] = "INSERT";
|
||||
names[static_cast<unsigned>(Scancode::DELETE)] = "DELETE";
|
||||
names[static_cast<unsigned>(Scancode::ARROW_DOWN)] = "ARROW_DOWN";
|
||||
names[static_cast<unsigned>(Scancode::ARROW_RIGHT)] = "ARROW_RIGHT";
|
||||
names[static_cast<unsigned>(Scancode::ARROW_UP)] = "ARROW_UP";
|
||||
names[static_cast<unsigned>(Scancode::PAGE_DOWN)] = "PAGE_DOWN";
|
||||
names[static_cast<unsigned>(Scancode::PAGE_UP)] = "PAGE_UP";
|
||||
names[static_cast<unsigned>(Scancode::PRINT_SCREEN)] = "PRINT_SCREEN";
|
||||
names[static_cast<unsigned>(Scancode::PAUSE)] = "PAUSE";
|
||||
return names;
|
||||
}();
|
||||
//</editor-fold>
|
||||
|
||||
inline constexpr std::uint16_t PORT_PS2_DATA = 0x60;
|
||||
inline constexpr std::uint16_t PORT_PS2_STATUS = 0x64;
|
||||
inline constexpr std::uint8_t FLAG_PS2_OUTPUT_FULL = (1 << 0);
|
||||
@ -38,6 +322,8 @@ std::uint8_t gKeyboardBuffer[KEY_BUFFER_LENGTH];
|
||||
unsigned gBufferedKeys = 0;
|
||||
unsigned gKeyPos = 0;
|
||||
|
||||
constinit std::array<std::uint8_t, (MAX_SCANCODE + 7) / 8> gKeyStates;
|
||||
|
||||
__attribute__((no_caller_saved_registers))
|
||||
void pushKey(std::uint8_t data) noexcept
|
||||
{
|
||||
@ -48,10 +334,24 @@ void pushKey(std::uint8_t data) noexcept
|
||||
++gBufferedKeys;
|
||||
gKeyPos = (gKeyPos + 1) % KEY_BUFFER_LENGTH;
|
||||
}
|
||||
|
||||
void setKeyDown(Scancode scancode, bool down) noexcept
|
||||
{
|
||||
const std::uint16_t index = static_cast<std::uint16_t>(scancode);
|
||||
const std::uint16_t byte = index / 8;
|
||||
const std::uint16_t bit = index % 8;
|
||||
|
||||
if (down)
|
||||
{
|
||||
gKeyStates[byte] |= (1 << bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
gKeyStates[byte] &= ~(1 << bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace baos::ps2
|
||||
{
|
||||
inline bool waitForResponse(unsigned tries = -1) noexcept
|
||||
{
|
||||
for (unsigned t = 0; t < tries; ++t)
|
||||
@ -219,11 +519,20 @@ void isrKeyboard(InterruptFrame* interruptFrame) noexcept
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isKeyDown(Scancode scancode) noexcept
|
||||
{
|
||||
const std::uint16_t index = static_cast<std::uint16_t>(scancode);
|
||||
const std::uint16_t byte = index / 8;
|
||||
const std::uint16_t bit = index % 8;
|
||||
|
||||
return (gKeyStates[byte] & (1 << bit)) != 0;
|
||||
}
|
||||
|
||||
bool gNextIsRelease = false;
|
||||
bool gNextIsExtended = false;
|
||||
bool gNextIsMoreExtended = false;
|
||||
bool gNextIsExtendedest = false;
|
||||
bool gPrevWasExtendedest = false;
|
||||
bool gNextIsExtended = false; // we've scanned a 0xE0 and are waiting for the second half
|
||||
bool gNextIsMoreExtended = false; // we've scanned a 0xE0 and a 0x12, and are waiting for the rest of the print screen key (TODO: print screen up is probably broken!)
|
||||
bool gNextIsExtendedest = false; // this is getting hilarious... this basically means we're somewhere inside the 0xE1, 0x14, 0x77, 0xE1, 0xF0, 0x14, 0xF0, 0x77 sequence for the pause key
|
||||
bool gPrevWasExtendedest = false; // we just sent the pause key press, send a release after (because it doesn't get generated)
|
||||
|
||||
bool readKey(KeyEvent& outEvent) noexcept
|
||||
{
|
||||
@ -292,273 +601,61 @@ bool readKey(KeyEvent& outEvent) noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
scancode |= 0xE000;
|
||||
scancode |= 0x0100;
|
||||
}
|
||||
}
|
||||
outEvent.scancode = static_cast<Scancode>(scancode);
|
||||
outEvent.down = !gNextIsRelease;
|
||||
outEvent.repeat = false; // TODO
|
||||
outEvent.repeat = outEvent.down && isKeyDown(outEvent.scancode);
|
||||
|
||||
setKeyDown(outEvent.scancode, outEvent.down);
|
||||
|
||||
// reset state
|
||||
gNextIsExtendedest = gNextIsMoreExtended = gNextIsRelease = gNextIsExtended = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readChar(char& outChar) noexcept
|
||||
{
|
||||
KeyEvent event;
|
||||
while (readKey(event))
|
||||
{
|
||||
if (!event.down) {
|
||||
continue;
|
||||
}
|
||||
if (keyToChar(event.scancode, outChar)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* keyName(Scancode scancode) noexcept
|
||||
{
|
||||
switch (scancode)
|
||||
return SCANCODE_NAMES[static_cast<unsigned>(scancode)];
|
||||
}
|
||||
|
||||
bool keyToChar(Scancode scancode, char& outChar) noexcept
|
||||
{
|
||||
case Scancode::INVALID:
|
||||
default:
|
||||
return "INVALID";
|
||||
case Scancode::F9:
|
||||
return "F9";
|
||||
case Scancode::F5:
|
||||
return "F5";
|
||||
case Scancode::F3:
|
||||
return "F3";
|
||||
case Scancode::F1:
|
||||
return "F1";
|
||||
case Scancode::F2:
|
||||
return "F2";
|
||||
case Scancode::F12:
|
||||
return "F12";
|
||||
case Scancode::F10:
|
||||
return "F10";
|
||||
case Scancode::F8:
|
||||
return "F8";
|
||||
case Scancode::F6:
|
||||
return "F6";
|
||||
case Scancode::F4:
|
||||
return "F4";
|
||||
case Scancode::TAB:
|
||||
return "TAB";
|
||||
case Scancode::BACKTICK:
|
||||
return "BACKTICK";
|
||||
case Scancode::LEFT_ALT:
|
||||
return "LEFT_ALT";
|
||||
case Scancode::LEFT_SHIFT:
|
||||
return "LEFT_SHIFT";
|
||||
case Scancode::LEFT_CONTROL:
|
||||
return "LEFT_CONTROL";
|
||||
case Scancode::Q:
|
||||
return "Q";
|
||||
case Scancode::_1:
|
||||
return "_1";
|
||||
case Scancode::Z:
|
||||
return "Z";
|
||||
case Scancode::S:
|
||||
return "S";
|
||||
case Scancode::A:
|
||||
return "A";
|
||||
case Scancode::W:
|
||||
return "W";
|
||||
case Scancode::_2:
|
||||
return "_2";
|
||||
case Scancode::C:
|
||||
return "C";
|
||||
case Scancode::X:
|
||||
return "X";
|
||||
case Scancode::D:
|
||||
return "D";
|
||||
case Scancode::E:
|
||||
return "E";
|
||||
case Scancode::_4:
|
||||
return "_4";
|
||||
case Scancode::_3:
|
||||
return "_3";
|
||||
case Scancode::SPACE:
|
||||
return "SPACE";
|
||||
case Scancode::V:
|
||||
return "V";
|
||||
case Scancode::F:
|
||||
return "F";
|
||||
case Scancode::T:
|
||||
return "T";
|
||||
case Scancode::R:
|
||||
return "R";
|
||||
case Scancode::_5:
|
||||
return "_5";
|
||||
case Scancode::N:
|
||||
return "N";
|
||||
case Scancode::B:
|
||||
return "B";
|
||||
case Scancode::H:
|
||||
return "H";
|
||||
case Scancode::G:
|
||||
return "G";
|
||||
case Scancode::Y:
|
||||
return "Y";
|
||||
case Scancode::_6:
|
||||
return "_6";
|
||||
case Scancode::M:
|
||||
return "M";
|
||||
case Scancode::J:
|
||||
return "J";
|
||||
case Scancode::U:
|
||||
return "U";
|
||||
case Scancode::_7:
|
||||
return "_7";
|
||||
case Scancode::_8:
|
||||
return "_8";
|
||||
case Scancode::COMMA:
|
||||
return "COMMA";
|
||||
case Scancode::K:
|
||||
return "K";
|
||||
case Scancode::I:
|
||||
return "I";
|
||||
case Scancode::O:
|
||||
return "O";
|
||||
case Scancode::_0:
|
||||
return "_0";
|
||||
case Scancode::_9:
|
||||
return "_9";
|
||||
case Scancode::DOT:
|
||||
return "DOT";
|
||||
case Scancode::SLASH:
|
||||
return "SLASH";
|
||||
case Scancode::L:
|
||||
return "L";
|
||||
case Scancode::SEMICOLON:
|
||||
return "SEMICOLON";
|
||||
case Scancode::P:
|
||||
return "P";
|
||||
case Scancode::MINUS:
|
||||
return "MINUS";
|
||||
case Scancode::APOSTROPHE:
|
||||
return "APOSTROPHE";
|
||||
case Scancode::BRACKET_OPEN:
|
||||
return "BRACKET_OPEN";
|
||||
case Scancode::EQUALS:
|
||||
return "EQUALS";
|
||||
case Scancode::CAPSLOCK:
|
||||
return "CAPSLOCK";
|
||||
case Scancode::RIGHT_SHIFT:
|
||||
return "RIGHT_SHIFT";
|
||||
case Scancode::ENTER:
|
||||
return "ENTER";
|
||||
case Scancode::BRACKET_CLOSE:
|
||||
return "BRACKET_CLOSE";
|
||||
case Scancode::BACKSLASH:
|
||||
return "BACKSLASH";
|
||||
case Scancode::BACKSPACE:
|
||||
return "BACKSPACE";
|
||||
case Scancode::KP_1:
|
||||
return "KP_1";
|
||||
case Scancode::KP_4:
|
||||
return "KP_4";
|
||||
case Scancode::KP_7:
|
||||
return "KP_7";
|
||||
case Scancode::KP_0:
|
||||
return "KP_0";
|
||||
case Scancode::KP_DOT:
|
||||
return "KP_DOT";
|
||||
case Scancode::KP_2:
|
||||
return "KP_2";
|
||||
case Scancode::KP_5:
|
||||
return "KP_5";
|
||||
case Scancode::KP_6:
|
||||
return "KP_6";
|
||||
case Scancode::KP_8:
|
||||
return "KP_8";
|
||||
case Scancode::ESCAPE:
|
||||
return "ESCAPE";
|
||||
case Scancode::NUMLOCK:
|
||||
return "NUMLOCK";
|
||||
case Scancode::F11:
|
||||
return "F11";
|
||||
case Scancode::KP_PLUS:
|
||||
return "KP_PLUS";
|
||||
case Scancode::KP_3:
|
||||
return "KP_3";
|
||||
case Scancode::KP_MINUS:
|
||||
return "KP_MINUS";
|
||||
case Scancode::KP_ASTERISK:
|
||||
return "KP_ASTERISK";
|
||||
case Scancode::KP_9:
|
||||
return "KP_9";
|
||||
case Scancode::SCROLLOCK:
|
||||
return "SCROLLOCK";
|
||||
case Scancode::F7:
|
||||
return "F7";
|
||||
case Scancode::MM_WWW_SEARCH:
|
||||
return "MM_WWW_SEARCH";
|
||||
case Scancode::RIGHT_ALT:
|
||||
return "RIGHT_ALT";
|
||||
case Scancode::RIGHT_CONTROL:
|
||||
return "RIGHT_CONTROL";
|
||||
case Scancode::MM_PREV_TRACK:
|
||||
return "MM_PREV_TRACK";
|
||||
case Scancode::LEFT_GUI:
|
||||
return "LEFT_GUI";
|
||||
case Scancode::MM_WWW_FAVORITES:
|
||||
return "MM_WWW_FAVORITES";
|
||||
case Scancode::MM_VOLUME_DOWN:
|
||||
return "MM_VOLUME_DOWN";
|
||||
case Scancode::MM_MUTE:
|
||||
return "MM_MUTE";
|
||||
case Scancode::RIGHT_GUI:
|
||||
return "RIGHT_GUI";
|
||||
case Scancode::MM_WWW_STOP:
|
||||
return "MM_WWW_STOP";
|
||||
case Scancode::MM_CALCULATOR:
|
||||
return "MM_CALCULATOR";
|
||||
case Scancode::APPS:
|
||||
return "APPS";
|
||||
case Scancode::MM_WWW_FORWARD:
|
||||
return "MM_WWW_FORWARD";
|
||||
case Scancode::MM_VOLUME_UP:
|
||||
return "MM_VOLUME_UP";
|
||||
case Scancode::MM_PLAY_PAUSE:
|
||||
return "MM_PLAY_PAUSE";
|
||||
case Scancode::ACPI_POWER:
|
||||
return "ACPI_POWER";
|
||||
case Scancode::MM_WWW_BACK:
|
||||
return "MM_WWW_BACK";
|
||||
case Scancode::MM_WWW_HOME:
|
||||
return "MM_WWW_HOME";
|
||||
case Scancode::MM_STOP:
|
||||
return "MM_STOP";
|
||||
case Scancode::ACPI_SLEEP:
|
||||
return "ACPI_SLEEP";
|
||||
case Scancode::MM_MY_COMPUTER:
|
||||
return "MM_MY_COMPUTER";
|
||||
case Scancode::MM_EMAIL:
|
||||
return "MM_EMAIL";
|
||||
case Scancode::KP_SLASH:
|
||||
return "KP_SLASH";
|
||||
case Scancode::MM_NEXT_TRACK:
|
||||
return "MM_NEXT_TRACK";
|
||||
case Scancode::MM_MEDIA_SELECT:
|
||||
return "MM_MEDIA_SELECT";
|
||||
case Scancode::KP_ENTER:
|
||||
return "KP_ENTER";
|
||||
case Scancode::ACPI_WAKE:
|
||||
return "ACPI_WAKE";
|
||||
case Scancode::END:
|
||||
return "END";
|
||||
case Scancode::ARROW_LEFT:
|
||||
return "ARROW_LEFT";
|
||||
case Scancode::HOME:
|
||||
return "HOME";
|
||||
case Scancode::INSERT:
|
||||
return "INSERT";
|
||||
case Scancode::DELETE:
|
||||
return "DELETE";
|
||||
case Scancode::ARROW_DOWN:
|
||||
return "ARROW_DOWN";
|
||||
case Scancode::ARROW_RIGHT:
|
||||
return "ARROW_RIGHT";
|
||||
case Scancode::ARROW_UP:
|
||||
return "ARROW_UP";
|
||||
case Scancode::PAGE_DOWN:
|
||||
return "PAGE_DOWN";
|
||||
case Scancode::PAGE_UP:
|
||||
return "PAGE_UP";
|
||||
case Scancode::PRINT_SCREEN:
|
||||
return "PRINT_SCREEN";
|
||||
case Scancode::PAUSE:
|
||||
return "PAUSE";
|
||||
}
|
||||
const Keymap& keymap = KEYMAP_DE_DE;
|
||||
char result = '\0';
|
||||
if (isKeyDown(Scancode::RIGHT_ALT))
|
||||
{
|
||||
result = keymap.altGredKeys[static_cast<unsigned>(scancode)];
|
||||
}
|
||||
else if (isKeyDown(Scancode::LEFT_SHIFT) || isKeyDown(Scancode::RIGHT_SHIFT))
|
||||
{
|
||||
result = keymap.shiftedKeys[static_cast<unsigned>(scancode)];
|
||||
}
|
||||
else
|
||||
{
|
||||
result = keymap.regularKeys[static_cast<unsigned>(scancode)];
|
||||
}
|
||||
if (result != '\0')
|
||||
{
|
||||
outChar = result;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,8 @@ void kernel_main()
|
||||
|
||||
std::puts("This is BadAppleOS and everything is fine!\n");
|
||||
|
||||
__enterUsermode(SEGIDX_USER_CODE, SEGIDX_USER_DATA, &tss.rsp0, &main);
|
||||
// __enterUsermode(SEGIDX_USER_CODE, SEGIDX_USER_DATA, &tss.rsp0, &main);
|
||||
main(); // for now run it in kernel mode, user mode doesn't work yet
|
||||
while (true)
|
||||
{
|
||||
ps2::KeyEvent event;
|
||||
|
Loading…
x
Reference in New Issue
Block a user