Started implementing a C++ stdlib. And improved the print function by adding newline support and scrolling.
This commit is contained in:
parent
0b05970c71
commit
1756b6a1a9
@ -26,6 +26,8 @@ os_sources = Split('''
|
|||||||
src/kernel/startup.cpp
|
src/kernel/startup.cpp
|
||||||
|
|
||||||
src/os/tty.cpp
|
src/os/tty.cpp
|
||||||
|
|
||||||
|
src/stdlib/string.cpp
|
||||||
''')
|
''')
|
||||||
env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0]} {crtbegin_o} $_LIBFLAGS {crtend_o} {crtn_o[0]}')
|
env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0]} {crtbegin_o} $_LIBFLAGS {crtend_o} {crtn_o[0]}')
|
||||||
|
|
||||||
|
14
include/cstring
Normal file
14
include/cstring
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_CSTRING_HPP_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_CSTRING_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
using ::strlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_CSTRING_HPP_INCLUDED)
|
15
include/detail/attributes.h
Normal file
15
include/detail/attributes.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_DETAIL_ATTRIBUTES_H_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_DETAIL_ATTRIBUTES_H_INCLUDED
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define BA_CXX_NODISCARD [[nodiscard]]
|
||||||
|
#define BA_CXX_NOEXCEPT noexcept
|
||||||
|
#else
|
||||||
|
#define BA_CXX_NODISCARD
|
||||||
|
#define BA_CXX_NOEXCEPT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_DETAIL_ATTRIBUTES_H_INCLUDED)
|
@ -35,17 +35,12 @@ struct VgaDoubleColor
|
|||||||
VgaColor background : 4 = VgaColor::BLACK;
|
VgaColor background : 4 = VgaColor::BLACK;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] size_t strlen(const char* str); // TODO: move to standard lib
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void setColor(VgaDoubleColor color);
|
void setColor(VgaDoubleColor color);
|
||||||
void putEntryAt(char chr, VgaDoubleColor color, size_t posX, size_t posY);
|
void putEntryAt(char chr, VgaDoubleColor color, size_t posX, size_t posY);
|
||||||
void putChar(char chr);
|
void putChar(char chr);
|
||||||
void write(const char* data, size_t size);
|
void write(const char* data, size_t size);
|
||||||
|
void write(const char* data);
|
||||||
inline void write(const char* data)
|
|
||||||
{
|
|
||||||
write(data, strlen(data));
|
|
||||||
}
|
|
||||||
} // namespace tty
|
} // namespace tty
|
||||||
|
|
||||||
#endif // OS_TTY_HPP_INCLUDED
|
#endif // OS_TTY_HPP_INCLUDED
|
||||||
|
19
include/string.h
Normal file
19
include/string.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_STRING_H_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_STRING_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "./detail/attributes.h"
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
BA_CXX_NODISCARD size_t strlen(const char* str) BA_CXX_NOEXCEPT;
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !defined(BAD_APPLE_OS_STRING_H_INCLUDED)
|
@ -1,5 +1,3 @@
|
|||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "os/tty.hpp"
|
#include "os/tty.hpp"
|
||||||
|
|
||||||
@ -17,7 +15,15 @@ extern "C" void kernel_main(void)
|
|||||||
{
|
{
|
||||||
/* Initialize terminal interface */
|
/* Initialize terminal interface */
|
||||||
tty::initialize();
|
tty::initialize();
|
||||||
|
|
||||||
/* Newline support is left as an exercise. */
|
|
||||||
tty::write("Hello, kernel World!\n");
|
tty::write("Hello, kernel World!\n");
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
for (char chr = 'A'; chr <= 'Z'; ++chr)
|
||||||
|
{
|
||||||
|
char buf[2] = {chr, '\n'};
|
||||||
|
tty::write(buf, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
#include "os/tty.hpp"
|
#include "os/tty.hpp"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace tty
|
namespace tty
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
@ -8,6 +10,11 @@ namespace
|
|||||||
inline const size_t VGA_WIDTH = 80;
|
inline const size_t VGA_WIDTH = 80;
|
||||||
inline const size_t VGA_HEIGHT = 25;
|
inline const size_t VGA_HEIGHT = 25;
|
||||||
|
|
||||||
|
size_t gTerminalRow = 0;
|
||||||
|
size_t gTerminalColumn = 0;
|
||||||
|
VgaDoubleColor gTerminalColor = VgaDoubleColor();
|
||||||
|
uint16_t* gTerminalBuffer = reinterpret_cast<uint16_t*>(0xB8000);
|
||||||
|
|
||||||
constexpr uint8_t vgaEntryColor(VgaDoubleColor color)
|
constexpr uint8_t vgaEntryColor(VgaDoubleColor color)
|
||||||
{
|
{
|
||||||
return static_cast<uint8_t>(color.foreground) | static_cast<uint8_t>(color.background) << 4;
|
return static_cast<uint8_t>(color.foreground) | static_cast<uint8_t>(color.background) << 4;
|
||||||
@ -18,19 +25,28 @@ constexpr uint16_t vgaEntry(const unsigned char chr, const VgaDoubleColor color)
|
|||||||
return static_cast<uint16_t>(chr) | static_cast<uint16_t>(vgaEntryColor(color) << 8);
|
return static_cast<uint16_t>(chr) | static_cast<uint16_t>(vgaEntryColor(color) << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t gTerminalRow = 0;
|
void newline()
|
||||||
size_t gTerminalColumn = 0;
|
|
||||||
VgaDoubleColor gTerminalColor = VgaDoubleColor();
|
|
||||||
uint16_t* gTerminalBuffer = reinterpret_cast<uint16_t*>(0xB8000);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t strlen(const char* str) // TODO: move to standard lib
|
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
gTerminalColumn = 0;
|
||||||
while (str[len] != '\0') {
|
if (gTerminalRow < VGA_HEIGHT - 1)
|
||||||
++len;
|
{
|
||||||
|
++gTerminalRow;
|
||||||
}
|
}
|
||||||
return len;
|
else
|
||||||
|
{
|
||||||
|
// scrolling up
|
||||||
|
for (size_t y = 0; y < VGA_HEIGHT - 1; ++y)
|
||||||
|
{
|
||||||
|
// TODO: this is where I'd put my memcpy. If I had one.
|
||||||
|
for (size_t x = 0; x < VGA_WIDTH; ++x)
|
||||||
|
{
|
||||||
|
const size_t indexTo = y * VGA_WIDTH + x;
|
||||||
|
const size_t indexFrom = (y + 1) * VGA_WIDTH + x;
|
||||||
|
gTerminalBuffer[indexTo] = gTerminalBuffer[indexFrom];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
@ -61,11 +77,7 @@ void putChar(char chr)
|
|||||||
putEntryAt(chr, gTerminalColor, gTerminalColumn, gTerminalRow);
|
putEntryAt(chr, gTerminalColor, gTerminalColumn, gTerminalRow);
|
||||||
if (++gTerminalColumn == VGA_WIDTH)
|
if (++gTerminalColumn == VGA_WIDTH)
|
||||||
{
|
{
|
||||||
gTerminalColumn = 0;
|
newline();
|
||||||
if (++gTerminalRow == VGA_HEIGHT)
|
|
||||||
{
|
|
||||||
gTerminalRow = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +85,19 @@ void write(const char* data, size_t size)
|
|||||||
{
|
{
|
||||||
for (size_t idx = 0; idx < size; idx++)
|
for (size_t idx = 0; idx < size; idx++)
|
||||||
{
|
{
|
||||||
putChar(data[idx]);
|
if (data[idx] == '\n')
|
||||||
|
{
|
||||||
|
newline();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putChar(data[idx]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write(const char* data)
|
||||||
|
{
|
||||||
|
write(data, std::strlen(data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
14
src/stdlib/string.cpp
Normal file
14
src/stdlib/string.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
size_t strlen(const char* str) noexcept
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
while (str[len] != '\0') {
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user