Implemented something like a console (still WIP).

This commit is contained in:
Patrick 2024-01-20 02:52:58 +01:00
parent f4bad14fcd
commit c41a9a1034
9 changed files with 151 additions and 20 deletions

View File

@ -4,6 +4,7 @@
#if !defined(BAD_APPLE_OS_CSTDIO_INCLUDED)
#define BAD_APPLE_OS_CSTDIO_INCLUDED
#include <string>
#include <stdio.h>
namespace std
@ -21,6 +22,9 @@ using ::fgets;
using ::fgetc;
using ::getc;
using ::getchar;
bool fgetline(FILE* stream, std::string& outLine) noexcept;
inline bool getline(std::string& outLine) noexcept { return fgetline(stdin, outLine); }
}
#endif // !defined(BAD_APPLE_OS_CSTDIO_INCLUDED)

View File

@ -78,6 +78,15 @@ public:
}
constexpr basic_string& operator=(std::nullptr_t) = delete;
constexpr basic_string& operator+=(value_type chr) noexcept
{
return append(chr);
}
constexpr basic_string& operator+=(const basic_string& other) noexcept
{
return append(other);
}
[[nodiscard]] constexpr reference operator[](size_type pos) noexcept { return _data[pos]; }
[[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept { return _data[pos]; }
@ -88,8 +97,8 @@ public:
[[nodiscard]] constexpr reference front() noexcept { return _data.front(); }
[[nodiscard]] constexpr const_reference front() const noexcept { return _data.front(); }
[[nodiscard]] constexpr reference back() noexcept { return _data.back(); }
[[nodiscard]] constexpr const_reference back() const noexcept { return _data.back(); }
[[nodiscard]] constexpr reference back() noexcept { return _data.at(size() - 1); }
[[nodiscard]] constexpr const_reference back() const noexcept { return _data.at(size() - 1); }
[[nodiscard]] constexpr pointer data() noexcept { return _data.data(); }
[[nodiscard]] constexpr const_pointer data() const noexcept { return _data.data(); }
@ -117,6 +126,29 @@ public:
_data.back() = value_type(0);
}
constexpr basic_string& append(value_type chr) noexcept
{
_data.back() = chr;
_data.push_back(value_type());
return *this;
}
constexpr basic_string& append(const basic_string& other) noexcept
{
_data.reserve(_data.size() + other.size());
_data.resize(_data.size() - 1);
for (char chr : other)
{
_data.push_back(chr);
}
_data.push_back(value_type());
return *this;
}
constexpr void pop_back() noexcept
{
_data.pop_back();
_data.back() = value_type();
}
static inline size_type npos = size_type(-1);
};
using string = basic_string<char>;

View File

@ -214,6 +214,11 @@ public:
++_size;
}
constexpr void pop_back() noexcept
{
resize(size() - 1);
}
template<typename... TArgs>
constexpr reference emplace_back(TArgs&&... args)
{

View File

@ -19,6 +19,14 @@ private:
public:
[[nodiscard]] bool full() const noexcept { return mBufferedElements == SIZE; }
[[nodiscard]] bool empty() const noexcept { return mBufferedElements == 0; }
[[nodiscard]] std::size_t size() const noexcept { return mBufferedElements; }
[[nodiscard]] T& operator[](std::size_t index) noexcept { return at(index); }
[[nodiscard]] const T& operator[](std::size_t index) const noexcept { return at(index); }
[[nodiscard]] T& at(std::size_t index) noexcept { return mElements[(index + mPosition) % SIZE]; }
[[nodiscard]] const T& at(std::size_t index) const noexcept { return mElements[(index + mPosition) % SIZE]; }
bool append(T element) noexcept
{
if (full()) {
@ -29,6 +37,7 @@ public:
mPosition = (mPosition + 1) % SIZE;
return true;
}
bool next(T& outElement) noexcept
{
if (empty()) {

View File

@ -4,6 +4,7 @@
#if !defined(OS_TTY_HPP_INCLUDED)
#define OS_TTY_HPP_INCLUDED 1
#include <string>
#include <stddef.h>
#include <stdint.h>
@ -39,9 +40,12 @@ void initialize() noexcept;
void setColor(VgaDoubleColor color) noexcept;
void putEntryAt(char chr, VgaDoubleColor color, size_t posX, size_t posY) noexcept;
void putChar(char chr) noexcept;
void deleteChar() noexcept;
void write(const char* data, size_t size) noexcept;
void write(const char* data) noexcept;
[[nodiscard]] const std::string& readLine() noexcept;
bool setPSFFont(const void* data, size_t length) noexcept;
} // namespace tty

View File

@ -5,12 +5,12 @@ extern "C" void main()
{
// __asm__ __volatile__("cli");
std::string cmd;
while(true)
{
int chr = std::getchar();
if (chr != std::EOF)
{
putchar(chr);
}
std::printf("> ");
std::getline(cmd);
cmd.pop_back(); // pop the \n
std::printf("Your command: %s\n", cmd.c_str());
}
}

View File

@ -3,7 +3,6 @@
#include <algorithm>
#include <stdarg.h>
#include "drivers/ps2.hpp"
#include "os/serial.hpp"
#include "os/tty.hpp"
#include "os/tools/printf_helper.hpp"
@ -32,6 +31,41 @@ public:
}
return true;
}
bool readLine(std::string& outLine) noexcept
{
outLine.clear();
while(true)
{
while (mBuffer.empty()) {
if (!underflow()) {
return false;
}
}
// first check if there is a \n in the stream
std::size_t count = mBuffer.size();
for (std::size_t idx = 0; idx < mBuffer.size(); ++idx)
{
if (mBuffer[idx] == '\n')
{
count = idx + 1;
break;
}
}
outLine.reserve(outLine.size() + count);
for (std::size_t idx = 0; idx < count; ++idx)
{
char chr = '\0';
mBuffer.next(chr);
outLine.append(chr);
}
if (outLine.back() == '\n')
{
return true;
}
}
}
};
namespace
@ -64,16 +98,8 @@ class StdinFile : public __file
public:
bool underflow() noexcept override
{
while (mBuffer.empty())
{
char chr;
while (!mBuffer.full() && baos::ps2::readChar(chr))
{
for (char chr : tty::readLine()) {
mBuffer.append(chr);
if (chr == '\n') {
break;
}
}
}
return true;
}
@ -186,3 +212,11 @@ char* fgets(char* buffer, int count, FILE* stream) noexcept
}
} // extern "C"
namespace std
{
bool fgetline(FILE* stream, std::string& outLine) noexcept
{
return stream->readLine(outLine);
}
}

View File

@ -51,6 +51,7 @@ const constinit Keymap KEYMAP_EN_US = []()
keymap.set(Scancode::Y, 'y', 'Y');
keymap.set(Scancode::Z, 'z', 'Z');
keymap.set(Scancode::ENTER, '\n');
keymap.set(Scancode::BACKSPACE, '\b');
keymap.set(Scancode::MINUS, '-', '_');
keymap.set(Scancode::EQUALS, '=', '+');
keymap.set(Scancode::TAB, '\t');
@ -63,6 +64,7 @@ const constinit Keymap KEYMAP_EN_US = []()
keymap.set(Scancode::COMMA, ',', '<');
keymap.set(Scancode::DOT, '.', '>');
keymap.set(Scancode::SLASH, '/', '?');
keymap.set(Scancode::SPACE, ' ');
keymap.set(Scancode::KP_ENTER, '\n');
keymap.set(Scancode::KP_0, '0');
@ -122,9 +124,10 @@ const constinit Keymap KEYMAP_DE_DE = []()
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::Y, 'z', 'Z');
keymap.set(Scancode::Z, 'y', 'Y');
keymap.set(Scancode::ENTER, '\n');
keymap.set(Scancode::BACKSPACE, '\b');
keymap.set(Scancode::MINUS, '?' /* ß */, '?', '\\');
keymap.set(Scancode::EQUALS, '`' /* ´ */, '`');
keymap.set(Scancode::TAB, '\t');
@ -137,6 +140,7 @@ const constinit Keymap KEYMAP_DE_DE = []()
keymap.set(Scancode::COMMA, ',', ';');
keymap.set(Scancode::DOT, '.', ':');
keymap.set(Scancode::SLASH, '-', '_');
keymap.set(Scancode::SPACE, ' ');
keymap.set(Scancode::KP_ENTER, '\n');
keymap.set(Scancode::KP_0, '0');

View File

@ -3,6 +3,7 @@
#include <cstring>
#include <vector>
#include "drivers/ps2.hpp"
#include "libs/psf.hpp"
#include "os/draw.hpp"
#include "os/resources/lat9-08.psf.hpp"
@ -19,6 +20,7 @@ VgaDoubleColor gTerminalColor = VgaDoubleColor();
// uint16_t* gTerminalBuffer = reinterpret_cast<uint16_t*>(0xB8000);
std::vector<uint16_t> gTerminalBuffer;
psf::Font gTerminalFont;
std::string gReadBuffer;
constexpr uint8_t vgaEntryColor(VgaDoubleColor color)
{
@ -81,6 +83,17 @@ void putChar(char chr) noexcept
}
}
void deleteChar() noexcept
{
if (gTerminalColumn > 0)
{
--gTerminalColumn;
putEntryAt(' ', gTerminalColor, gTerminalColumn, gTerminalRow);
// TODO: store the length of each line so we can return to the previous one
}
}
void write(const char* data, size_t size) noexcept
{
for (size_t idx = 0; idx < size; idx++)
@ -94,6 +107,32 @@ void write(const char* data) noexcept
write(data, std::strlen(data));
}
const std::string& readLine() noexcept
{
gReadBuffer.clear();
while(true)
{
char chr = '\0';
putChar('_');
while (!baos::ps2::readChar(chr)); // TODO: arrow key navigation and stuff
deleteChar();
if (chr == '\b')
{
if (!gReadBuffer.empty())
{
gReadBuffer.pop_back();
deleteChar();
}
continue;
}
gReadBuffer += chr;
putChar(chr);
if (chr == '\n') {
return gReadBuffer;
}
}
}
bool setPSFFont(const void* data, size_t length) noexcept
{
psf::Font newFont;