1

Namespace classes

This commit is contained in:
2022-12-07 21:17:27 +01:00
parent c87e691588
commit 1aa029922f
124 changed files with 8796 additions and 17762 deletions

View File

@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.14)
target_sources(device PUBLIC
${CHURLOS_SRC_DIR}/device/graphics/CGA.cc
${CHURLOS_SRC_DIR}/device/graphics/CGA_Stream.cc
${CHURLOS_SRC_DIR}/device/graphics/Fonts.cc
${CHURLOS_SRC_DIR}/device/graphics/LFBgraphics.cc
${CHURLOS_SRC_DIR}/device/graphics/VESA.cc
)

View File

@ -8,10 +8,9 @@ include_directories(${CHURLOS_SRC_DIR})
add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES})
# Add subdirectories
add_subdirectory(demo)
add_subdirectory(event)
add_subdirectory(exception)
add_subdirectory(interrupt)
add_subdirectory(log)
add_subdirectory(memory)
add_subdirectory(process)
add_subdirectory(system)

View File

@ -1,17 +0,0 @@
cmake_minimum_required(VERSION 3.14)
target_sources(kernel PUBLIC
${CHURLOS_SRC_DIR}/kernel/demo/ArrayDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/bmp_hhu.cc
${CHURLOS_SRC_DIR}/kernel/demo/HeapDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/KeyboardDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/MainMenu.cc
${CHURLOS_SRC_DIR}/kernel/demo/PagingDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/PCSPKdemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/PreemptiveThreadDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/SmartPointerDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/StringDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/TextDemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/VBEdemo.cc
${CHURLOS_SRC_DIR}/kernel/demo/VectorDemo.cc
)

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.14)
target_sources(kernel PUBLIC
${CHURLOS_SRC_DIR}/kernel/log/Logger.cc
${CHURLOS_SRC_DIR}/kernel/exception/Bluescreen.cc
)

View File

@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 3.14)
target_sources(kernel PUBLIC
${CHURLOS_SRC_DIR}/kernel/interrupt/Bluescreen.cc
${CHURLOS_SRC_DIR}/kernel/interrupt/IntDispatcher.cc
)

View File

@ -9,6 +9,8 @@ add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES})
# Add subdirectories
add_subdirectory(async)
add_subdirectory(demo)
add_subdirectory(graphics)
add_subdirectory(mem)
add_subdirectory(stream)
add_subdirectory(util)
add_subdirectory(string)

View File

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.14)
target_sources(lib PUBLIC
${CHURLOS_SRC_DIR}/lib/demo/ArrayDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/bmp_hhu.cc
${CHURLOS_SRC_DIR}/lib/demo/HeapDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/KeyboardDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/MainMenu.cc
${CHURLOS_SRC_DIR}/lib/demo/PagingDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/PCSPKdemo.cc
${CHURLOS_SRC_DIR}/lib/demo/PreemptiveThreadDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/SmartPointerDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/StringDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/TextDemo.cc
${CHURLOS_SRC_DIR}/lib/demo/VBEdemo.cc
${CHURLOS_SRC_DIR}/lib/demo/VectorDemo.cc
)

View File

@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.14)
target_sources(lib PUBLIC
${CHURLOS_SRC_DIR}/lib/graphics/Fonts.cc
)

View File

@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.14)
target_sources(lib PUBLIC
${CHURLOS_SRC_DIR}/lib/stream/CGA_Stream.cc
${CHURLOS_SRC_DIR}/lib/stream/Logger.cc
${CHURLOS_SRC_DIR}/lib/stream/OutStream.cc
${CHURLOS_SRC_DIR}/lib/stream/StringBuffer.cc
)

View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.14)
target_sources(lib PUBLIC
${CHURLOS_SRC_DIR}/lib/string/String.cc
${CHURLOS_SRC_DIR}/lib/string/StringView.cc
)

View File

@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.14)
target_sources(lib PUBLIC
${CHURLOS_SRC_DIR}/lib/util/String.cc
${CHURLOS_SRC_DIR}/lib/util/StringBuffer.cc
${CHURLOS_SRC_DIR}/lib/util/StringView.cc
)

View File

@ -13,9 +13,11 @@
// 16-Bit Code aufrufen, siehe Konstruktor und Aufruf in startup.asm
extern "C" {
void bios_call();
void bios_call();
}
namespace Device {
// in startup.asm im GDT-Eintrag so festgeschrieben!
constexpr const unsigned int BIOS16_CODE_MEMORY_START = 0x24000;
@ -23,7 +25,7 @@ constexpr const unsigned int BIOS16_CODE_MEMORY_START = 0x24000;
constexpr const unsigned int BIOS16_PARAM_BASE = 0x26000;
// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h)
BIOScall_params* BC_params = reinterpret_cast<BIOScall_params*>(BIOS16_PARAM_BASE);
BIOScall_params *BC_params = reinterpret_cast<BIOScall_params *>(BIOS16_PARAM_BASE);
/*****************************************************************************
* Methode: BIOS::BIOS *
@ -33,7 +35,7 @@ BIOScall_params* BC_params = reinterpret_cast<BIOScall_params*>(BIOS16_PARAM_BAS
* im 4. GDT-Eintrag (siehe startup.asm). *
*****************************************************************************/
BIOS::BIOS() {
auto* codeAddr = reinterpret_cast<uint8_t*>(BIOS16_CODE_MEMORY_START);
auto *codeAddr = reinterpret_cast<uint8_t *>(BIOS16_CODE_MEMORY_START);
// mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird)
*codeAddr = 0x66;
@ -313,7 +315,7 @@ BIOS::BIOS() {
* Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. *
*****************************************************************************/
void BIOS::Int(uint8_t inter) {
auto* ptr = reinterpret_cast<uint8_t*>(BIOS16_CODE_MEMORY_START);
auto *ptr = reinterpret_cast<uint8_t *>(BIOS16_CODE_MEMORY_START);
// Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...)
*(ptr + 48) = static_cast<uint8_t>(inter);
@ -322,3 +324,5 @@ void BIOS::Int(uint8_t inter) {
bios_call();
CPU::enable_int();
}
}

View File

@ -12,6 +12,8 @@
#include <cstdint>
namespace Device {
// Speicherseite fuer Rueckgabewerte von BIOS-Aufrufen
constexpr const unsigned int RETURN_MEM = 0x9F000;
@ -52,4 +54,6 @@ public:
static void Int(uint8_t inter);
};
}
#endif

View File

@ -12,9 +12,11 @@
#ifndef CPU_include__
#define CPU_include__
namespace Device {
class CPU {
public:
CPU(const CPU& copy) = delete; // Verhindere Kopieren
CPU(const CPU &copy) = delete; // Verhindere Kopieren
CPU() = default;
@ -44,9 +46,11 @@ public:
static inline unsigned long long int rdtsc() {
unsigned long long int ret;
asm volatile("rdtsc"
: "=A"(ret));
: "=A"(ret));
return ret;
}
};
}
#endif

View File

@ -15,12 +15,14 @@
#include "lib/mem/Memory.h"
#include <cstdint>
namespace Device {
const IOport CGA::index_port(0x3d4);
const IOport CGA::data_port(0x3d5);
const bse::span<CGA::cga_char_t, CGA::ROWS * CGA::COLUMNS> CGA::SCREEN{reinterpret_cast<CGA::cga_char_t*>(0xb8000U)};
const bse::span<CGA::cga_line_t, CGA::ROWS> CGA::SCREEN_ROWS{reinterpret_cast<CGA::cga_line_t*>(0xb8000U)};
CGA::cga_page_t* const CGA::SCREEN_PAGE {reinterpret_cast<CGA::cga_page_t*>(0xb8000U)};
const Container::span<CGA::cga_char_t, CGA::ROWS * CGA::COLUMNS> CGA::SCREEN{reinterpret_cast<CGA::cga_char_t *>(0xb8000U)};
const Container::span<CGA::cga_line_t, CGA::ROWS> CGA::SCREEN_ROWS{reinterpret_cast<CGA::cga_line_t *>(0xb8000U)};
CGA::cga_page_t *const CGA::SCREEN_PAGE{reinterpret_cast<CGA::cga_page_t *>(0xb8000U)};
/*****************************************************************************
* Methode: CGA::setpos *
@ -50,7 +52,7 @@ void CGA::setpos(uint8_t x, uint8_t y) {
* *
* Rückgabewerte: x und y *
*****************************************************************************/
void CGA::getpos(uint8_t& x, uint8_t& y) {
void CGA::getpos(uint8_t &x, uint8_t &y) {
/* Hier muess Code eingefuegt werden */
@ -86,7 +88,7 @@ void CGA::show(uint8_t x, uint8_t y, char character, uint8_t attrib) {
return;
}
cga_char_t* pos = SCREEN[x + y * COLUMNS];
cga_char_t *pos = SCREEN[x + y * COLUMNS];
pos->cga_char = character;
pos->cga_attribute = attrib;
}
@ -102,7 +104,7 @@ void CGA::show(uint8_t x, uint8_t y, char character, uint8_t attrib) {
* n Laenger der Zeichenkette *
* attrib Attributbyte fuer alle Zeichen der Zeichenkette *
*****************************************************************************/
void CGA::print(const bse::string_view string, uint8_t attrib) const {
void CGA::print(const String::string_view string, uint8_t attrib) const {
/* Hier muess Code eingefuegt werden */
@ -110,7 +112,7 @@ void CGA::print(const bse::string_view string, uint8_t attrib) const {
uint8_t cursor_y = 0; // Don't poll registers every stroke
getpos(cursor_x, cursor_y);
for (char current : string) {
for (char current: string) {
if (current == '\n') {
cursor_x = 0;
cursor_y = cursor_y + 1;
@ -160,10 +162,10 @@ void CGA::scrollup() const {
/* Hier muss Code eingefuegt werden */
// Move up
bse::memcpy<cga_line_t>(SCREEN_ROWS[0], SCREEN_ROWS[1], ROWS - 1);
Memory::memcpy<cga_line_t>(SCREEN_ROWS[0], SCREEN_ROWS[1], ROWS - 1);
// Clear last line
bse::zero<cga_line_t>(SCREEN_ROWS[ROWS - 1]);
Memory::zero<cga_line_t>(SCREEN_ROWS[ROWS - 1]);
}
/*****************************************************************************
@ -175,7 +177,7 @@ void CGA::clear() {
/* Hier muess Code eingefuegt werden */
bse::zero<cga_page_t>(SCREEN_PAGE);
Memory::zero<cga_page_t>(SCREEN_PAGE);
setpos(0, 0);
}
@ -196,6 +198,8 @@ uint8_t CGA::attribute(CGA::color bg, CGA::color fg, bool blink) {
/* Hier muess Code eingefuegt werden */
return static_cast<int>(blink) << 7 // B0000000
| (bg & 0x7) << 4 // 0HHH0000 (Hintergrund)
| (fg & 0xF); // 0000VVVV (Vordergrund)
| (bg & 0x7) << 4 // 0HHH0000 (Hintergrund)
| (fg & 0xF); // 0000VVVV (Vordergrund)
}
}

View File

@ -16,10 +16,12 @@
#include <cstdint>
#include "device/port/IOport.h"
#include "lib/util/Array.h"
#include "lib/util/Span.h"
#include "lib/util/String.h"
#include "lib/util/StringView.h"
#include "lib/container/Array.h"
#include "lib/container/Span.h"
#include "lib/string/String.h"
#include "lib/string/StringView.h"
namespace Device {
class CGA {
private:
@ -28,7 +30,7 @@ private:
public:
// Copy Konstrutkor unterbinden
CGA(const CGA& copy) = delete;
CGA(const CGA &copy) = delete;
// Konstruktur mit Initialisierung der Ports
CGA() {
@ -58,11 +60,15 @@ public:
} color;
// Standardzeichenfarbe
enum { STD_ATTR = BLACK << 4 | LIGHT_GREY };
enum {
STD_ATTR = BLACK << 4 | LIGHT_GREY
};
// Groesse des Bildschirms (25 Zeilen, 80 Spalten)
enum { ROWS = 25,
COLUMNS = 80 };
enum {
ROWS = 25,
COLUMNS = 80
};
// Easier access to memory (also easier copying of lines/pages etc)
struct cga_char_t {
@ -72,28 +78,28 @@ public:
struct cga_line_t {
// Can use these arrays since they don't have memory overhead (except for the methods that are elsewhere)
bse::array<cga_char_t, COLUMNS> cga_line;
Container::array<cga_char_t, COLUMNS> cga_line;
};
struct cga_page_t {
bse::array<cga_line_t, ROWS> cga_page;
Container::array<cga_line_t, ROWS> cga_page;
};
static const bse::span<cga_char_t, ROWS * COLUMNS> SCREEN;
static const bse::span<cga_line_t, ROWS> SCREEN_ROWS;
static cga_page_t* const SCREEN_PAGE; // No span because can't address anything in [0, 1]
static const Container::span<cga_char_t, ROWS * COLUMNS> SCREEN;
static const Container::span<cga_line_t, ROWS> SCREEN_ROWS;
static cga_page_t *const SCREEN_PAGE; // No span because can't address anything in [0, 1]
// Setzen des Cursors in Spalte x und Zeile y.
static void setpos(uint8_t x, uint8_t y);
// Abfragen der Cursorpostion
static void getpos(uint8_t& x, uint8_t& y) ;
static void getpos(uint8_t &x, uint8_t &y);
// Anzeige eines Zeichens mit Attribut an einer bestimmten Stelle
static void show(uint8_t x, uint8_t y, char character, uint8_t attrib = STD_ATTR);
// Anzeige mehrerer Zeichen ab der aktuellen Cursorposition
void print(const bse::string_view substring, uint8_t attrib = STD_ATTR) const;
void print(String::string_view substring, uint8_t attrib = STD_ATTR) const;
// Verschiebt den Bildschirminhalt um eine Zeile nach oben.
// Neue Zeile am unteren Bildrand mit Leerzeichen fuellen
@ -106,4 +112,6 @@ public:
static uint8_t attribute(CGA::color bg, CGA::color fg, bool blink);
};
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,264 +0,0 @@
// vim: set et ts=4 sw=4:
/* Acorn-like font definition, with PC graphics characters */
constexpr const uint8_t acorndata_8x8[] = {
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
/* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
/* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
/* 03 */ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^C */
/* 04 */ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^D */
/* 05 */ 0x00, 0x18, 0x3c, 0xe7, 0xe7, 0x3c, 0x18, 0x00, /* ^E */
/* 06 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 07 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 09 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 0F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 10 */ 0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00, /* |> */
/* 11 */ 0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00, /* <| */
/* 12 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 13 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 14 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 15 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 16 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 17 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 19 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 1A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 1B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 1C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 1D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 1E */ 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, /* /\ */
/* 1F */ 0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, /* \/ */
/* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
/* 21 */ 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, /* ! */
/* 22 */ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */
/* 23 */ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, /* # */
/* 24 */ 0x0C, 0x3F, 0x68, 0x3E, 0x0B, 0x7E, 0x18, 0x00, /* $ */
/* 25 */ 0x60, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x06, 0x00, /* % */
/* 26 */ 0x38, 0x6C, 0x6C, 0x38, 0x6D, 0x66, 0x3B, 0x00, /* & */
/* 27 */ 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' */
/* 28 */ 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, /* ( */
/* 29 */ 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, /* ) */
/* 2A */ 0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00, /* * */
/* 2B */ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, /* + */
/* 2C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, /* , */
/* 2D */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* - */
/* 2E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, /* . */
/* 2F */ 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, /* / */
/* 30 */ 0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x3C, 0x00, /* 0 */
/* 31 */ 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* 1 */
/* 32 */ 0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* 2 */
/* 33 */ 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00, /* 3 */
/* 34 */ 0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x0C, 0x00, /* 4 */
/* 35 */ 0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00, /* 5 */
/* 36 */ 0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00, /* 6 */
/* 37 */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, /* 7 */
/* 38 */ 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, /* 8 */
/* 39 */ 0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00, /* 9 */
/* 3A */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, /* : */
/* 3B */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, /* ; */
/* 3C */ 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, /* < */
/* 3D */ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, /* = */
/* 3E */ 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, /* > */
/* 3F */ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, /* ? */
/* 40 */ 0x3C, 0x66, 0x6E, 0x6A, 0x6E, 0x60, 0x3C, 0x00, /* @ */
/* 41 */ 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* A */
/* 42 */ 0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00, /* B */
/* 43 */ 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00, /* C */
/* 44 */ 0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00, /* D */
/* 45 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00, /* E */
/* 46 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00, /* F */
/* 47 */ 0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00, /* G */
/* 48 */ 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* H */
/* 49 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* I */
/* 4A */ 0x3E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00, /* J */
/* 4B */ 0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00, /* K */
/* 4C */ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, /* L */
/* 4D */ 0x63, 0x77, 0x7F, 0x6B, 0x6B, 0x63, 0x63, 0x00, /* M */
/* 4E */ 0x66, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x66, 0x00, /* N */
/* 4F */ 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* O */
/* 50 */ 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, /* P */
/* 51 */ 0x3C, 0x66, 0x66, 0x66, 0x6A, 0x6C, 0x36, 0x00, /* Q */
/* 52 */ 0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00, /* R */
/* 53 */ 0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00, /* S */
/* 54 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* T */
/* 55 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* U */
/* 56 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* V */
/* 57 */ 0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x77, 0x63, 0x00, /* W */
/* 58 */ 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, /* X */
/* 59 */ 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, /* Y */
/* 5A */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00, /* Z */
/* 5B */ 0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00, /* [ */
/* 5C */ 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, /* \ */
/* 5D */ 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, /* ] */
/* 5E */ 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^ */
/* 5F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /* _ */
/* 60 */ 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
/* 61 */ 0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, /* a */
/* 62 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, /* b */
/* 63 */ 0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00, /* c */
/* 64 */ 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, /* d */
/* 65 */ 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, /* e */
/* 66 */ 0x1C, 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x00, /* f */
/* 67 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* g */
/* 68 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* h */
/* 69 */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, /* i */
/* 6A */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x70, /* j */
/* 6B */ 0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00, /* k */
/* 6C */ 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, /* l */
/* 6D */ 0x00, 0x00, 0x36, 0x7F, 0x6B, 0x6B, 0x63, 0x00, /* m */
/* 6E */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* n */
/* 6F */ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, /* o */
/* 70 */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, /* p */
/* 71 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x07, /* q */
/* 72 */ 0x00, 0x00, 0x6C, 0x76, 0x60, 0x60, 0x60, 0x00, /* r */
/* 73 */ 0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00, /* s */
/* 74 */ 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x1C, 0x00, /* t */
/* 75 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, /* u */
/* 76 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* v */
/* 77 */ 0x00, 0x00, 0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, /* w */
/* 78 */ 0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, /* x */
/* 79 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* y */
/* 7A */ 0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* z */
/* 7B */ 0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00, /* { */
/* 7C */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* | */
/* 7D */ 0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00, /* } */
/* 7E */ 0x31, 0x6B, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, /* ~ */
/* 7F */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*  */
/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 81 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 82 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 83 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 84 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 85 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 86 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 87 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 89 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 8A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 8B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 8C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 8D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 8E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 8F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 91 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 92 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 93 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 94 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 95 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 97 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 99 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 9A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 9B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 9C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 9D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 9E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 9F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* A9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* AF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* B0 */ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
/* B1 */ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
/* B2 */ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
/* B3 */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
/* B4 */ 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
/* B5 */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
/* B6 */ 0x66, 0x66, 0x66, 0xe6, 0x66, 0x66, 0x66, 0x66,
/* B7 */ 0x00, 0x00, 0x00, 0xfe, 0x66, 0x66, 0x66, 0x66,
/* B8 */ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
/* B9 */ 0x66, 0x66, 0xe6, 0x06, 0xe6, 0x66, 0x66, 0x66,
/* BA */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
/* BB */ 0x00, 0x00, 0xfe, 0x06, 0xe6, 0x66, 0x66, 0x66,
/* BC */ 0x66, 0x66, 0xe6, 0x06, 0xfe, 0x00, 0x00, 0x00,
/* BD */ 0x66, 0x66, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
/* BE */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
/* BF */ 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18,
/* C0 */ 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
/* C1 */ 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00,
/* C2 */ 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18,
/* C3 */ 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
/* C4 */ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
/* C5 */ 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
/* C6 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
/* C7 */ 0x66, 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66,
/* C8 */ 0x66, 0x66, 0x67, 0x60, 0x7f, 0x00, 0x00, 0x00,
/* C9 */ 0x00, 0x00, 0x7f, 0x60, 0x67, 0x66, 0x66, 0x66,
/* CA */ 0x66, 0x66, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00,
/* CB */ 0x00, 0x00, 0xff, 0x00, 0xe7, 0x66, 0x66, 0x66,
/* CC */ 0x66, 0x66, 0x67, 0x60, 0x67, 0x66, 0x66, 0x66,
/* CD */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
/* CE */ 0x66, 0x66, 0xe7, 0x00, 0xe7, 0x66, 0x66, 0x66,
/* CF */ 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
/* D0 */ 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00,
/* D1 */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
/* D2 */ 0x00, 0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66,
/* D3 */ 0x66, 0x66, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00,
/* D4 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
/* D5 */ 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
/* D6 */ 0x00, 0x00, 0x00, 0x7f, 0x66, 0x66, 0x66, 0x66,
/* D7 */ 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66,
/* D8 */ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
/* D9 */ 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00,
/* DA */ 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18,
/* DB */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* DC */ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
/* DD */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
/* DE */ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
/* DF */ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
/* E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* E9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* EA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* EB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* EC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* ED */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* EE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* EF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* FA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* FB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* FC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* FD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* FE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#undef FONTDATAMAX

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,265 +0,0 @@
// vim: set et ts=4 sw=4:
constexpr const uint32_t FONTDATAMAX_SUN8x16 = 4096;
constexpr const uint8_t fontdata_sun_8x16[FONTDATAMAX_SUN8x16] = {
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,
/* */ 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00,
/* */ 0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff,
/* */ 0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,
/* */ 0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00,
/* */ 0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*!*/ 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
/*"*/ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*#*/ 0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00,
/*$*/ 0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00,
/*%*/ 0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00,
/*&*/ 0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*'*/ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*(*/ 0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00,
/*)*/ 0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00,
/***/ 0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
/*+*/ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
/*,*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
/*-*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*.*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00,
/*0*/ 0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*1*/ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00,
/*2*/ 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00,
/*3*/ 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*4*/ 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00,
/*5*/ 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*6*/ 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*7*/ 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
/*8*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*9*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00,
/*:*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
/*;*/ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
/*<*/ 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00,
/*=*/ 0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*>*/ 0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
/*?*/ 0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
/*@*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00,
/*A*/ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/*B*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00,
/*C*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00,
/*D*/ 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00,
/*E*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
/*F*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*G*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00,
/*H*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/*I*/ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*J*/ 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
/*K*/ 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
/*L*/ 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
/*M*/ 0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00,
/*N*/ 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/*O*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*P*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*Q*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00,
/*R*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
/*S*/ 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*T*/ 0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*U*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*V*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
/*W*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00,
/*X*/ 0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00,
/*Y*/ 0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*Z*/ 0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00,
/*[*/ 0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00,
/*\*/ 0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00,
/*]*/ 0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00,
/*^*/ 0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*_*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,
/* */ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*a*/ 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*b*/ 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00,
/*c*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*d*/ 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*e*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*f*/ 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*g*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00,
/*h*/ 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
/*i*/ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*j*/ 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,
/*k*/ 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00,
/*l*/ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/*m*/ 0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00,
/*n*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
/*o*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*p*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00,
/*q*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00,
/*r*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
/*s*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00,
/*t*/ 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00,
/*u*/ 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/*v*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
/*w*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00,
/*x*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00,
/*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
/*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
/*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
/*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00,
/* */ 0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00,
/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00,
/* */ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00,
/* */ 0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00,
/* */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
/* */ 0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00,
/* */ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00,
/* */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
/* */ 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,
/* */ 0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
/* */ 0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
/* */ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
/* */ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,
/* */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
/* */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00,
/* */ 0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
#undef FONTDATAMAX

View File

@ -1,19 +0,0 @@
// Jakob Falke, oostubs
// Github: https://gitlab.cs.fau.de/um15ebek/oostubs
// vim: set et ts=4 sw=4:
#include "Fonts.h"
#include "Font_8x16.h"
#include "Font_8x8.h"
#include "Font_acorn_8x8.h"
#include "Font_pearl_8x8.h"
#include "Font_sun_12x22.h"
#include "Font_sun_8x16.h"
const Font_8x16 std_font_8x16;
const Font_8x8 std_font_8x8;
const Font_acorn_8x8 acorn_font_8x8;
const Font_pearl_8x8 pearl_font_8x8;
const Font_sun_12x22 sun_font_12x22;
const Font_sun_8x16 sun_font_8x16;

View File

@ -14,8 +14,11 @@
#include "LFBgraphics.h"
namespace Device {
/* Hilfsfunktionen */
void swap(uint32_t* a, uint32_t* b);
void swap(uint32_t *a, uint32_t *b);
uint16_t abs(int32_t a);
/*****************************************************************************
@ -37,7 +40,7 @@ uint16_t abs(int32_t a);
*****************************************************************************/
inline void LFBgraphics::drawMonoBitmap(uint32_t x, uint32_t y,
uint32_t width, uint32_t height,
const uint8_t* bitmap, uint32_t color) const {
const uint8_t *bitmap, uint32_t color) const {
// Breite in Bytes
uint16_t width_byte = width / 8 + ((width % 8 != 0) ? 1 : 0);
@ -68,8 +71,8 @@ inline void LFBgraphics::drawMonoBitmap(uint32_t x, uint32_t y,
* Beschreibung: Gibt eine Zeichenkette mit gewaehlter Schrift an der *
* Position x,y aus. *
*****************************************************************************/
void LFBgraphics::drawString(const Font& fnt, uint32_t x, uint32_t y,
uint32_t col, const char* str, uint32_t len) const {
void LFBgraphics::drawString(const Graphics::Font &fnt, uint32_t x, uint32_t y,
uint32_t col, const char *str, uint32_t len) const {
for (uint32_t i = 0; i < len; ++i) {
drawMonoBitmap(x, y, fnt.get_char_width(), fnt.get_char_height(), fnt.getChar(*(str + i)), col);
x += fnt.get_char_width();
@ -85,14 +88,14 @@ void LFBgraphics::drawString(const Font& fnt, uint32_t x, uint32_t y,
* Beschreibung: Zeichnen eines Pixels. *
*****************************************************************************/
void LFBgraphics::drawPixel(uint32_t x, uint32_t y, uint32_t col) const {
auto* ptr = reinterpret_cast<uint8_t*>(lfb);
auto *ptr = reinterpret_cast<uint8_t *>(lfb);
if (hfb == 0 || lfb == 0) {
return;
}
if (mode == BUFFER_INVISIBLE) {
ptr = reinterpret_cast<uint8_t*>(hfb);
ptr = reinterpret_cast<uint8_t *>(hfb);
}
// Pixel ausserhalb des sichtbaren Bereichs?
@ -102,33 +105,33 @@ void LFBgraphics::drawPixel(uint32_t x, uint32_t y, uint32_t col) const {
// Adresse des Pixels berechnen und Inhalt schreiben
switch (bpp) {
case 8:
ptr += (x + y * xres);
*ptr = col;
return;
case 15:
case 16:
ptr += (2 * x + 2 * y * xres);
*ptr = col;
return;
case 24:
ptr += (3 * x + 3 * y * xres);
*ptr = (col & 0xFF);
ptr++;
*ptr = ((col >> 8) & 0xFF);
ptr++;
*ptr = ((col >> 16) & 0xFF);
ptr;
return;
case 32:
ptr += (4 * x + 4 * y * xres);
*ptr = (col & 0xFF);
ptr++;
*ptr = ((col >> 8) & 0xFF);
ptr++;
*ptr = ((col >> 16) & 0xFF);
ptr;
return;
case 8:
ptr += (x + y * xres);
*ptr = col;
return;
case 15:
case 16:
ptr += (2 * x + 2 * y * xres);
*ptr = col;
return;
case 24:
ptr += (3 * x + 3 * y * xres);
*ptr = (col & 0xFF);
ptr++;
*ptr = ((col >> 8) & 0xFF);
ptr++;
*ptr = ((col >> 16) & 0xFF);
ptr;
return;
case 32:
ptr += (4 * x + 4 * y * xres);
*ptr = (col & 0xFF);
ptr++;
*ptr = ((col >> 8) & 0xFF);
ptr++;
*ptr = ((col >> 16) & 0xFF);
ptr;
return;
}
}
@ -153,7 +156,8 @@ void LFBgraphics::drawStraightLine(uint32_t x1, uint32_t y1, uint32_t x2, uint32
// (x1, y1)---(x2, y1)
// | |
// (x1, y2)---(x2, y2)
void LFBgraphics::drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const {
void
LFBgraphics::drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const {
drawStraightLine(x1, y1, x2, y1, col);
drawStraightLine(x2, y1, x2, y2, col);
drawStraightLine(x1, y2, x2, y2, col);
@ -164,23 +168,24 @@ void LFBgraphics::drawCircle(unsigned int x, unsigned int y, unsigned int rad, u
// TODO
}
void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const uint8_t* pixel_data) const {
const uint8_t* ptr;
void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp,
const uint8_t *pixel_data) const {
const uint8_t *ptr;
for (unsigned int x = 0; x < width; ++x) {
for (unsigned int y = 0; y < height; ++y) {
ptr = pixel_data + (x + y * width) * bytes_pp;
switch (bytes_pp) {
case 2:
// TODO: Never tested, probably doesn't work
drawPixel(x, y, RGB_24(*ptr & 0b11111000, ((*ptr & 0b111) << 3) | (*(ptr + 1) >> 5),
*(ptr + 1) & 0b11111)); // RGB 565
break;
case 3:
case 4:
// Alpha gets ignored anyway
drawPixel(x, y, RGB_24(*ptr, *(ptr + 1), *(ptr + 2)));
break;
case 2:
// TODO: Never tested, probably doesn't work
drawPixel(x, y, RGB_24(*ptr & 0b11111000, ((*ptr & 0b111) << 3) | (*(ptr + 1) >> 5),
*(ptr + 1) & 0b11111)); // RGB 565
break;
case 3:
case 4:
// Alpha gets ignored anyway
drawPixel(x, y, RGB_24(*ptr, *(ptr + 1), *(ptr + 2)));
break;
}
}
}
@ -192,7 +197,7 @@ void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned i
* Beschreibung: Bildschirm loeschen. *
*****************************************************************************/
void LFBgraphics::clear() const {
auto* ptr = reinterpret_cast<uint32_t*>(lfb);
auto *ptr = reinterpret_cast<uint32_t *>(lfb);
unsigned int i;
if (hfb == 0 || lfb == 0) {
@ -200,31 +205,31 @@ void LFBgraphics::clear() const {
}
if (mode == 0) {
ptr = reinterpret_cast<uint32_t*>(hfb);
ptr = reinterpret_cast<uint32_t *>(hfb);
}
switch (bpp) {
case 8:
for (i = 0; i < ((xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
case 15:
case 16:
for (i = 0; i < (2 * (xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
case 24:
for (i = 0; i < (3 * (xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
case 32:
for (i = 0; i < (4 * (xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
case 8:
for (i = 0; i < ((xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
case 15:
case 16:
for (i = 0; i < (2 * (xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
case 24:
for (i = 0; i < (3 * (xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
case 32:
for (i = 0; i < (4 * (xres / 4) * yres); i++) {
*(ptr++) = 0;
}
return;
}
}
@ -243,8 +248,8 @@ void LFBgraphics::setDrawingBuff(int v) {
* Beschreibung: Kopiert den versteckten Puffer in den sichtbaren LFB. *
*****************************************************************************/
void LFBgraphics::copyHiddenToVisible() const {
auto* sptr = reinterpret_cast<uint32_t*>(hfb);
auto* dptr = reinterpret_cast<uint32_t*>(lfb);
auto *sptr = reinterpret_cast<uint32_t *>(hfb);
auto *dptr = reinterpret_cast<uint32_t *>(lfb);
uint32_t i;
if (hfb == 0 || lfb == 0) {
@ -252,31 +257,31 @@ void LFBgraphics::copyHiddenToVisible() const {
}
switch (bpp) {
case 8:
for (i = 0; i < ((xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
case 15:
case 16:
for (i = 0; i < (2 * (xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
case 24:
for (i = 0; i < (3 * (xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
case 32:
for (i = 0; i < (4 * (xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
case 8:
for (i = 0; i < ((xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
case 15:
case 16:
for (i = 0; i < (2 * (xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
case 24:
for (i = 0; i < (3 * (xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
case 32:
for (i = 0; i < (4 * (xres / 4) * yres); i++) {
*(dptr++) = *(sptr++);
}
return;
}
}
void swap(uint32_t* a, uint32_t* b) {
void swap(uint32_t *a, uint32_t *b) {
uint32_t h = *a;
*a = *b;
@ -289,3 +294,5 @@ uint16_t abs(int32_t a) {
}
return a;
}
}

View File

@ -15,7 +15,9 @@
#ifndef LFBgraphics_include__
#define LFBgraphics_include__
#include "Fonts.h"
#include "lib/graphics/Fonts.h"
namespace Device {
// Hilfsfunktionen um Farbwerte fuer einen Pixel zu erzeugen
constexpr uint32_t RGB_24(uint8_t r, uint8_t g, uint8_t b) {
@ -23,17 +25,17 @@ constexpr uint32_t RGB_24(uint8_t r, uint8_t g, uint8_t b) {
}
constexpr const bool BUFFER_INVISIBLE = false;
constexpr const bool BUFFER_VISIBLE = true;
constexpr const bool BUFFER_VISIBLE = true;
class LFBgraphics {
private:
// Hilfsfunktion fuer drawString
void drawMonoBitmap(uint32_t x, uint32_t y,
uint32_t width, uint32_t height,
const uint8_t* bitmap, uint32_t col) const;
const uint8_t *bitmap, uint32_t col) const;
public:
LFBgraphics(const LFBgraphics& copy) = delete; // Verhindere Kopieren
LFBgraphics(const LFBgraphics &copy) = delete; // Verhindere Kopieren
LFBgraphics() : mode(BUFFER_VISIBLE) {};
@ -44,15 +46,18 @@ public:
uint8_t mode; // Zeichnen im sichtbaren = 1 oder unsichtbaren = 0 Puffer
void clear() const;
void drawPixel(uint32_t x, uint32_t y, uint32_t col) const;
void drawString(const Font& fnt, uint32_t x, uint32_t y, uint32_t col, const char* str, uint32_t len) const;
void drawString(const Graphics::Font &fnt, uint32_t x, uint32_t y, uint32_t col, const char *str, uint32_t len) const;
void drawCircle(uint32_t x, uint32_t y, uint32_t rad, uint32_t col) const;
void drawStraightLine(uint32_t x1, uint32_t y1, uint32_t x2, unsigned int y2, unsigned int col) const;
void drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const;
void drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const uint8_t* pixel_data) const;
void drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const uint8_t *pixel_data) const;
// stellt ein, ob in den sichtbaren Puffer gezeichnet wird
void setDrawingBuff(int v);
@ -61,4 +66,6 @@ public:
void copyHiddenToVisible() const;
};
}
#endif

View File

@ -11,6 +11,8 @@
#include "VESA.h"
#include "device/bios/BIOS.h"
namespace Device {
// Informationen ueber einen VESA-Grafikmodus
// (siehe http://wiki.osdev.org/VESA_Video_Modes)
struct VbeModeInfoBlock {
@ -76,7 +78,7 @@ bool VESA::initGraphicMode(uint16_t mode) {
BC_params->DI = RETURN_MEM & 0xF;
BIOS::Int(0x10);
VbeInfoBlock* ib = reinterpret_cast<VbeInfoBlock*>(RETURN_MEM);
auto *ib = reinterpret_cast<VbeInfoBlock *>(RETURN_MEM);
// Signaturen pruefen
if (BC_params->AX != 0x004F) {
@ -89,14 +91,14 @@ bool VESA::initGraphicMode(uint16_t mode) {
return false;
}
// kout << "TotalVideoMemory: " << ((ib->TotalMemory*65536) / (1024*1024)) << " MB" << endl;
// Kernel::kout << "TotalVideoMemory: " << ((ib->TotalMemory*65536) / (1024*1024)) << " MB" << endl;
// Gewuenschten Grafikmodus aus Antwort suchen
auto* modePtr = reinterpret_cast<uint16_t*>((ib->VideoModePtr[1] << 4) + ib->VideoModePtr[0]);
auto *modePtr = reinterpret_cast<uint16_t *>((ib->VideoModePtr[1] << 4) + ib->VideoModePtr[0]);
for (uint32_t i = 0; modePtr[i] != 0xFFFF; ++i) {
// Gewuenschter Grafikmodus gefunden?
if (modePtr[i] == mode) {
VbeModeInfoBlock* minf = reinterpret_cast<VbeModeInfoBlock*>(RETURN_MEM);
auto *minf = reinterpret_cast<VbeModeInfoBlock *>(RETURN_MEM);
// Weitere Infos ueber diesen Grafikmodus abfragen
BC_params->AX = 0x4F01;
@ -129,3 +131,5 @@ bool VESA::initGraphicMode(uint16_t mode) {
log.error() << "Grafikmodus nicht gefunden." << endl;
return false;
}
}

View File

@ -12,7 +12,9 @@
#define VESA_include__
#include "LFBgraphics.h"
#include "kernel/log/Logger.h"
#include "lib/stream/Logger.h"
namespace Device {
// Ausgewaehlte Grafikmodi mit Mode-Nummer
constexpr const uint16_t MODE_640_480_16BITS = 0x111;
@ -28,7 +30,7 @@ private:
NamedLogger log;
public:
VESA(const VESA& copy) = delete; // Verhindere Kopieren
VESA(const VESA &copy) = delete; // Verhindere Kopieren
VESA() : log("VESA") {}
@ -36,7 +38,10 @@ public:
// Bestimmten Grafikmodus einschalten
bool initGraphicMode(uint16_t mode);
static void initTextMode();
};
}
#endif

View File

@ -10,6 +10,8 @@
#ifndef Key_include__
#define Key_include__
namespace Device {
class Key {
// Kopieren erlaubt!
@ -45,8 +47,11 @@ public:
// ASCII, SCANCODE: Setzen und Abfragen von Ascii und Scancode
void ascii(uint8_t a) { asc = a; }
void scancode(uint8_t s) { scan = s; }
uint8_t ascii() const { return asc; }
uint8_t scancode() const { return scan; }
//
@ -88,14 +93,23 @@ public:
// Funktionen zum Abfragen von SHIFT, ALT, CTRL usw.
//
bool shift() const { return (modi & mbit::shift) != 0; }
bool alt_left() const { return (modi & mbit::alt_left) != 0; }
bool alt_right() const { return (modi & mbit::alt_right) != 0; }
bool ctrl_left() const { return (modi & mbit::ctrl_left) != 0; }
bool ctrl_right() const { return (modi & mbit::ctrl_right) != 0; }
bool caps_lock() const { return (modi & mbit::caps_lock) != 0; }
bool num_lock() const { return (modi & mbit::num_lock) != 0; }
bool scroll_lock() const { return (modi & mbit::scroll_lock) != 0; }
bool alt() const { return alt_left() || alt_right(); }
bool ctrl() const { return ctrl_left() || ctrl_right(); }
operator char() const { return static_cast<char>(asc); }
@ -114,4 +128,6 @@ public:
};
};
}
#endif

View File

@ -12,40 +12,42 @@
#include "kernel/system/Globals.h"
#include "Key.h"
namespace Device {
const IOport Keyboard::ctrl_port(0x64);
const IOport Keyboard::data_port(0x60);
/* Tabellen fuer ASCII-Codes (Klassenvariablen) intiialisieren */
constexpr const uint8_t Keyboard::normal_tab[] = {
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 225, 39, '\b',
0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 129, '+', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 148, 132, '^', 0, '#',
'y', '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, 0, 0, 0, '<', 0, 0};
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 225, 39, '\b',
0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 129, '+', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 148, 132, '^', 0, '#',
'y', '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, 0, 0, 0, '<', 0, 0};
constexpr const uint8_t Keyboard::shift_tab[] = {
0, 0, '!', '"', 21, '$', '%', '&', '/', '(', ')', '=', '?', 96, 0,
0, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 154, '*', 0,
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 153, 142, 248, 0, 39,
'Y', '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, 0, 0, 0, 0, 0, 0, '>', 0, 0};
0, 0, '!', '"', 21, '$', '%', '&', '/', '(', ')', '=', '?', 96, 0,
0, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 154, '*', 0,
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 153, 142, 248, 0, 39,
'Y', '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, 0, 0, 0, 0, 0, 0, '>', 0, 0};
constexpr const uint8_t Keyboard::alt_tab[] = {
0, 0, 0, 253, 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, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0};
0, 0, 0, 253, 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, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0};
constexpr const uint8_t Keyboard::asc_num_tab[] = {
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ','};
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ','};
constexpr const uint8_t Keyboard::scan_num_tab[] = {
8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51};
8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51};
/*****************************************************************************
* Methode: Keyboard::key_decoded *
@ -71,26 +73,26 @@ bool Keyboard::key_decoded() {
// ignoriert werden.
if (code & break_bit) {
code &= ~break_bit; // Der Break-Code einer Taste ist gleich dem
// Make-Code mit gesetzten break_bit.
// Make-Code mit gesetzten break_bit.
switch (code) {
case 42:
case 54:
gather.shift(false);
break;
case 56:
if (prefix == prefix1) {
gather.alt_right(false);
} else {
gather.alt_left(false);
}
break;
case 29:
if (prefix == prefix1) {
gather.ctrl_right(false);
} else {
gather.ctrl_left(false);
}
break;
case 42:
case 54:
gather.shift(false);
break;
case 56:
if (prefix == prefix1) {
gather.alt_right(false);
} else {
gather.alt_left(false);
}
break;
case 29:
if (prefix == prefix1) {
gather.ctrl_right(false);
} else {
gather.ctrl_left(false);
}
break;
}
// Ein Prefix gilt immer nur fuer den unmittelbar nachfolgenden Code.
@ -110,52 +112,52 @@ bool Keyboard::key_decoded() {
// code der Taste fehlt.
switch (code) {
case 42:
case 54:
gather.shift(true);
break;
case 56:
if (prefix == prefix1) {
gather.alt_right(true);
} else {
gather.alt_left(true);
}
break;
case 29:
if (prefix == prefix1) {
gather.ctrl_right(true);
} else {
gather.ctrl_left(true);
}
break;
case 58:
gather.caps_lock(!gather.caps_lock());
set_led(led::caps_lock, gather.caps_lock());
break;
case 70:
gather.scroll_lock(!gather.scroll_lock());
set_led(led::scroll_lock, gather.scroll_lock());
break;
case 69: // Numlock oder Pause ?
if (gather.ctrl_left()) { // Pause Taste
// Auf alten Tastaturen konnte die Pause-Funktion wohl nur
// ueber Ctrl+NumLock erreicht werden. Moderne MF-II Tastaturen
// senden daher diese Codekombination, wenn Pause gemeint ist.
// Die Pause Taste liefert zwar normalerweise keinen ASCII-
// Code, aber Nachgucken schadet auch nicht. In jedem Fall ist
// die Taste nun komplett.
case 42:
case 54:
gather.shift(true);
break;
case 56:
if (prefix == prefix1) {
gather.alt_right(true);
} else {
gather.alt_left(true);
}
break;
case 29:
if (prefix == prefix1) {
gather.ctrl_right(true);
} else {
gather.ctrl_left(true);
}
break;
case 58:
gather.caps_lock(!gather.caps_lock());
set_led(led::caps_lock, gather.caps_lock());
break;
case 70:
gather.scroll_lock(!gather.scroll_lock());
set_led(led::scroll_lock, gather.scroll_lock());
break;
case 69: // Numlock oder Pause ?
if (gather.ctrl_left()) { // Pause Taste
// Auf alten Tastaturen konnte die Pause-Funktion wohl nur
// ueber Ctrl+NumLock erreicht werden. Moderne MF-II Tastaturen
// senden daher diese Codekombination, wenn Pause gemeint ist.
// Die Pause Taste liefert zwar normalerweise keinen ASCII-
// Code, aber Nachgucken schadet auch nicht. In jedem Fall ist
// die Taste nun komplett.
get_ascii_code();
done = true;
} else { // NumLock
gather.num_lock(!gather.num_lock());
set_led(led::num_lock, gather.num_lock());
}
break;
default: // alle anderen Tasten
// ASCII-Codes aus den entsprechenden Tabellen auslesen, fertig.
get_ascii_code();
done = true;
} else { // NumLock
gather.num_lock(!gather.num_lock());
set_led(led::num_lock, gather.num_lock());
}
break;
default: // alle anderen Tasten
// ASCII-Codes aus den entsprechenden Tabellen auslesen, fertig.
get_ascii_code();
done = true;
}
// Ein Prefix gilt immer nur fuer den unmittelbar nachfolgenden Code.
@ -183,9 +185,9 @@ void Keyboard::get_ascii_code() {
gather.scancode(Key::scan::div);
}
// Anhand der Modifierbits muss die richtige Tabelle ausgewaehlt
// werden. Der Einfachheit halber hat NumLock Vorrang vor Alt,
// Shift und CapsLock. Fuer Ctrl gibt es keine eigene Tabelle
// Anhand der Modifierbits muss die richtige Tabelle ausgewaehlt
// werden. Der Einfachheit halber hat NumLock Vorrang vor Alt,
// Shift und CapsLock. Fuer Ctrl gibt es keine eigene Tabelle
else if (gather.num_lock() && !prefix && code >= 71 && code <= 83) {
// Bei eingeschaltetem NumLock und der Betaetigung einer der
// Tasten des separaten Ziffernblocks (Codes 71-83), sollen
@ -288,7 +290,7 @@ void Keyboard::reboot() {
// Dem BIOS mitteilen, dass das Reset beabsichtigt war
// und kein Speichertest durchgefuehrt werden muss.
*reinterpret_cast<uint16_t*>(0x472) = 0x1234;
*reinterpret_cast<uint16_t *>(0x472) = 0x1234;
// Der Tastaturcontroller soll das Reset ausloesen.
do {
@ -332,7 +334,7 @@ void Keyboard::set_led(char led, bool on) {
// Registriert die Tastatur ISR im IntDispatcher
// und erlaubt den keyboard interrupt im PIC
void Keyboard::plugin() {
intdis.assign(IntDispatcher::keyboard, *this);
Kernel::intdis.assign(Kernel::IntDispatcher::keyboard, *this);
PIC::allow(PIC::keyboard);
}
@ -344,6 +346,8 @@ void Keyboard::trigger() {
if (key.ctrl_left() && key.alt_left() && static_cast<char>(key) == 'r') {
reboot();
} else if (key != 0) {
kevman.broadcast(key); // Send key to all subscribed threads
Kernel::kevman.broadcast(key); // Send key to all subscribed threads
}
}
}

View File

@ -16,7 +16,9 @@
#include "kernel/interrupt/ISR.h"
#include "device/port/IOport.h"
class Keyboard : public ISR {
namespace Device {
class Keyboard : public Kernel::ISR {
private:
uint8_t code; // Byte von Tastatur
uint8_t prefix; // Prefix von Tastatur
@ -28,33 +30,45 @@ private:
static const IOport data_port; // Ausgabe- (R) u. Eingabepuffer (W)
// Bits im Statusregister
enum { outb = 0x01,
inpb = 0x02,
auxb = 0x20 };
enum {
outb = 0x01,
inpb = 0x02,
auxb = 0x20
};
// Kommandos an die Tastatur
struct kbd_cmd {
enum { set_led = 0xed,
set_speed = 0xf3 };
enum {
set_led = 0xed,
set_speed = 0xf3
};
};
enum {
cpu_reset = 0xfe
};
enum { cpu_reset = 0xfe };
// Namen der LEDs
struct led {
enum { caps_lock = 4,
num_lock = 2,
scroll_lock = 1 };
enum {
caps_lock = 4,
num_lock = 2,
scroll_lock = 1
};
};
// Antworten der Tastatur
struct kbd_reply {
enum { ack = 0xfa };
enum {
ack = 0xfa
};
};
// Konstanten fuer die Tastaturdekodierung
enum { break_bit = 0x80,
prefix1 = 0xe0,
prefix2 = 0xe1 };
enum {
break_bit = 0x80,
prefix1 = 0xe0,
prefix2 = 0xe1
};
// Klassenvariablen
static const uint8_t normal_tab[];
@ -73,7 +87,7 @@ private:
Key key_hit();
public:
Keyboard(const Keyboard& copy) = delete; // Verhindere Kopieren
Keyboard(const Keyboard &copy) = delete; // Verhindere Kopieren
// Initialisierung der Tastatur.
Keyboard();
@ -98,4 +112,6 @@ public:
void trigger() override;
};
}
#endif

View File

@ -17,6 +17,8 @@
#include "PIC.h"
namespace Device {
IOport const PIC::IMR1(0x21); // interrupt mask register von PIC 1
IOport const PIC::IMR2(0xa1); // interrupt mask register von PIC 2
@ -103,3 +105,5 @@ bool PIC::status(uint8_t irq) {
uint8_t mask = 0x1 << (irq % 8);
return IMR & mask;
}
}

View File

@ -20,13 +20,15 @@
#include <cstdint>
#include "device/port/IOport.h"
namespace Device {
class PIC {
private:
static const IOport IMR1; // interrupt mask register von PIC 1
static const IOport IMR2; // interrupt mask register von PIC 2
public:
PIC(const PIC& copy) = delete; // Verhindere Kopieren
PIC(const PIC &copy) = delete; // Verhindere Kopieren
PIC() = default;
@ -49,4 +51,6 @@ public:
static bool status(uint8_t interrupt_device);
};
}
#endif

View File

@ -18,6 +18,8 @@
#include <cstdint>
namespace Device {
class IOport {
private:
// 16-Bit Adresse im I/O-Adressraum
@ -30,29 +32,29 @@ public:
// Byteweise Ausgabe eines Wertes ueber einen I/O-Port.
void outb(uint8_t val) const {
asm volatile("outb %0, %1"
:
: "a"(val), "Nd"(address));
:
: "a"(val), "Nd"(address));
}
// NOTE: I added this for easier init of COM1 port
void outb(uint8_t offset, uint8_t val) const {
asm volatile("outb %0, %1"
:
: "a"(val), "Nd"(static_cast<uint16_t>(address + offset)));
:
: "a"(val), "Nd"(static_cast<uint16_t>(address + offset)));
}
// Wortweise Ausgabe eines Wertes ueber einen I/O-Port.
void outw(uint16_t val) const {
asm volatile("outw %0, %1"
:
: "a"(val), "Nd"(address));
:
: "a"(val), "Nd"(address));
}
// 32-Bit Ausgabe eines Wertes ueber einen I/O-Port.
void outdw(uint32_t val) const {
asm volatile("outl %0, %1"
:
: "a"(val), "Nd"(address));
:
: "a"(val), "Nd"(address));
}
// Byteweises Einlesen eines Wertes ueber einen I/O-Port.
@ -60,8 +62,8 @@ public:
uint8_t ret;
asm volatile("inb %1, %0"
: "=a"(ret)
: "Nd"(address));
: "=a"(ret)
: "Nd"(address));
return ret;
}
@ -70,8 +72,8 @@ public:
uint8_t ret;
asm volatile("inb %1, %0"
: "=a"(ret)
: "Nd"(static_cast<uint16_t>(address + offset)));
: "=a"(ret)
: "Nd"(static_cast<uint16_t>(address + offset)));
return ret;
}
@ -80,8 +82,8 @@ public:
uint16_t ret;
asm volatile("inw %1, %0"
: "=a"(ret)
: "Nd"(address));
: "=a"(ret)
: "Nd"(address));
return ret;
}
@ -90,10 +92,12 @@ public:
unsigned int ret;
asm volatile("inl %1, %0"
: "=a"(ret)
: "Nd"(address));
: "=a"(ret)
: "Nd"(address));
return ret;
}
};
}
#endif

View File

@ -1,5 +1,7 @@
#include "SerialOut.h"
namespace Device {
const IOport SerialOut::com1(0x3f8);
SerialOut::SerialOut() {
@ -18,7 +20,7 @@ SerialOut::SerialOut() {
if (com1.inb() == 0xAE) {
// If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
com1.outb(4, 0x0F);
com1.outb(4, 0x0F);
}
}
@ -40,8 +42,10 @@ void SerialOut::write(const char a) {
com1.outb(a);
}
void SerialOut::write(const bse::string_view a) {
for (char current : a) {
void SerialOut::write(const String::string_view a) {
for (char current: a) {
write(current);
}
}
}

View File

@ -2,27 +2,35 @@
#define SerialOut_Include_H_
#include "IOport.h"
#include "lib/util/String.h"
#include "lib/util/StringView.h"
#include "lib/string/String.h"
#include "lib/string/StringView.h"
// NOTE: I took this code from https://wiki.osdev.org/Serial_Ports
namespace Device {
class SerialOut {
private:
static const IOport com1;
static int serial_received();
static int is_transmit_empty();
public:
SerialOut();
SerialOut(const SerialOut& copy) = delete;
SerialOut(const SerialOut &copy) = delete;
// Can't make singleton because atexit
static char read();
static void write(char a);
static void write(const bse::string_view a);
static void write(String::string_view a);
};
}
#endif

View File

@ -15,6 +15,8 @@
#include "PCSPK.h"
#include "kernel/system/Globals.h"
namespace Device {
const IOport PCSPK::control(0x43);
const IOport PCSPK::data2(0x42);
const IOport PCSPK::ppi(0x61);
@ -67,14 +69,15 @@ void PCSPK::off() {
* *
* Parameter: time (delay in ms) *
*****************************************************************************/
// TODO: Use timeservice
inline void PCSPK::delay(uint32_t time) {
/* Hier muess Code eingefuegt werden */
uint64_t start_time = systime;
uint64_t start_time = Kernel::systime;
// systime is incremented in 10ms steps
while ((systime - start_time) * 10 < time) {}
while ((Kernel::systime - start_time) * 10 < time) {}
}
/*****************************************************************************
@ -843,3 +846,5 @@ void PCSPK::aerodynamic() {
play(880.0, 122);
off();
}
}

View File

@ -18,6 +18,8 @@
#include <cstdint>
#include "device/port/IOport.h"
namespace Device {
// Note, Frequenz
constexpr const float C0 = 130.81;
constexpr const float C0X = 138.59;
@ -69,7 +71,7 @@ private:
static inline void delay(uint32_t time);
public:
PCSPK(const PCSPK& copy) = delete; // Verhindere Kopieren
PCSPK(const PCSPK &copy) = delete; // Verhindere Kopieren
// Konstruktor. Initialisieren der Ports.
PCSPK() = default;
@ -78,6 +80,7 @@ public:
// Demo Sounds
static void tetris();
static void aerodynamic();
// Ton abspielen
@ -87,4 +90,6 @@ public:
static void off();
};
}
#endif

View File

@ -11,6 +11,8 @@
#include "PIT.h"
#include "kernel/system/Globals.h"
namespace Device {
const IOport PIT::control(0x43);
const IOport PIT::data0(0x40);
@ -42,11 +44,12 @@ void PIT::interval(uint32_t us) {
* wird bei Ablauf des definierten Zeitintervalls die *
* Methode 'trigger' aufgerufen. *
*****************************************************************************/
// TODO: Use interruptservice
void PIT::plugin() {
/* hier muss Code eingefuegt werden */
intdis.assign(IntDispatcher::timer, *this);
Kernel::intdis.assign(Kernel::IntDispatcher::timer, *this);
PIC::allow(PIC::timer);
}
@ -58,6 +61,7 @@ void PIT::plugin() {
* aktualisieren und Thread wechseln durch Setzen der *
* Variable 'forceSwitch', wird in 'int_disp' behandelt. *
*****************************************************************************/
// TODO: Use timeservice + timeprovider
void PIT::trigger() {
/* hier muss Code eingefuegt werden */
@ -65,7 +69,7 @@ void PIT::trigger() {
// log << TRACE << "Incrementing systime" << endl;
// alle 10ms, Systemzeit weitersetzen
systime++;
Kernel::systime++;
// Bei jedem Tick einen Threadwechsel ausloesen.
// Aber nur wenn der Scheduler bereits fertig intialisiert wurde
@ -74,15 +78,19 @@ void PIT::trigger() {
/* hier muss Code eingefuegt werden */
// Indicator
if (systime - last_indicator_refresh >= 10) {
// TODO: Use timeservice
if (Kernel::systime - last_indicator_refresh >= 10) {
indicator_pos = (indicator_pos + 1) % 4;
CGA::show(79, 0, indicator[indicator_pos]);
last_indicator_refresh = systime;
last_indicator_refresh = Kernel::systime;
}
// TODO: Use schedulerservice
// Preemption
if (scheduler.preemption_enabled()) {
if (Kernel::scheduler.preemption_enabled()) {
// log << TRACE << "Preemption" << endl;
scheduler.preempt();
Kernel::scheduler.preempt();
}
}
}

View File

@ -13,23 +13,27 @@
#include "kernel/interrupt/ISR.h"
#include "device/port/IOport.h"
#include "lib/util/Array.h"
#include "lib/container/Array.h"
#include <cstdint>
class PIT : public ISR {
namespace Device {
class PIT : public Kernel::ISR {
private:
const static IOport control;
const static IOport data0;
enum { time_base = 838 }; /* ns */
enum {
time_base = 838
}; /* ns */
uint32_t timer_interval;
const bse::array<char, 4> indicator{'|', '/', '-', '\\'};
const Container::array<char, 4> indicator{'|', '/', '-', '\\'};
uint8_t indicator_pos = 0;
uint64_t last_indicator_refresh = 0;
public:
PIT(const PIT& copy) = delete; // Verhindere Kopieren
PIT(const PIT &copy) = delete; // Verhindere Kopieren
// ~PIT() override = default;
@ -52,4 +56,6 @@ public:
void trigger() override;
};
}
#endif

View File

@ -1,40 +0,0 @@
#include "ArrayDemo.h"
void ArrayDemo::run() {
bse::array<int, 10> arr1 {};
bse::array<int, 10> arr2 {};
kout.lock();
kout.clear();
kout << "Adding..." << endl;
for (int i = 0; i < 10; ++i) {
arr1[i] = i;
}
kout << "Iterator printing arr1:" << endl;
for (int i : arr1) {
kout << i << " ";
}
kout << endl;
kout << "Swapping arr1 and arr2..." << endl;
arr1.swap(arr2);
kout << "Iterator printing arr1:" << endl;
for (int i : arr1) {
kout << i << " ";
}
kout << endl;
kout << "Iterator printing arr2:" << endl;
for (int i : arr2) {
kout << i << " ";
}
kout << endl;
// arr1.swap(arr3); // Not possible as type/size has to match
kout.unlock();
scheduler.exit();
}

View File

@ -1,16 +0,0 @@
#include "PCSPKdemo.h"
void PCSPKdemo::run() {
kout.lock();
kout.clear();
kout << "Playing..." << endl;
kout.unlock();
(*melody)(); // This syntax is confusing as hell
kout.lock();
kout << "Finished" << endl;
kout.unlock();
scheduler.exit();
}

View File

@ -1,34 +0,0 @@
#include "PreemptiveThreadDemo.h"
void PreemptiveLoopThread::run() {
int cnt = 0;
while (running) {
// Basic synchronization by semaphore
kout.lock();
// Saving + restoring kout position doesn't help much as preemption still occurs
CGA_Stream::setpos(55, id);
kout << fillw(3) << id << fillw(0) << ": " << dec << cnt++ << endl;
kout.unlock();
}
scheduler.exit();
}
void PreemptiveThreadDemo::run() {
kout.lock();
kout.clear();
kout << "Preemptive Thread Demo:" << endl;
kout << "Readying LoopThreads" << endl;
for (unsigned int i = 0; i < number_of_threads; ++i) {
scheduler.ready<PreemptiveLoopThread>(i);
}
kout << "Exiting main thread" << endl;
kout.unlock();
scheduler.exit();
}

View File

@ -1,56 +0,0 @@
#include "StringDemo.h"
void StringDemo::run() {
kout.lock();
kout.clear();
log.info() << "Allocating new string" << endl;
bse::string str1 = "This is a dynamically allocated string!";
kout << str1 << endl;
log.info() << "Reassign string" << endl;
str1 = "Hello";
kout << str1 << " has length " << dec << str1.size() << endl;
kout << "Again with strlen: Hello has length " << dec << bse::strlen("Hello") << endl;
kout << "Adding strings: " << str1 << " + World" << endl;
log.info() << "Adding strings" << endl;
str1 = str1 + " World";
kout << str1 << endl;
kout << "Hello += World" << endl;
log.info() << "Hello += World" << endl;
bse::string str3 = "Hello";
str3 += " World";
kout << str3 << endl;
kout << "Hello World *= 3" << endl;
str3 *= 3;
kout << str3 << endl;
kout << "String iterator!" << endl;
for (const char c : str1) {
kout << c << " ";
}
kout << endl;
log.info() << "Allocating new string" << endl;
bse::string str2 = "Hello World";
kout << "str1 == str2: " << static_cast<int>(str1 == str2) << endl;
kout << "strcmp(Hello, Hello): " << bse::strcmp("Hello", "Hello") << endl;
log.info() << "Reassign str2" << endl;
str2 = "Hello";
bse::array<char, 5> arr{};
arr[0] = 'H';
arr[1] = 'e';
arr[2] = 'l';
arr[3] = 'l';
arr[4] = 'o';
kout << "bse::array<char, 5> to bse::string: " << static_cast<bse::string>(arr) << ", size: " << (bse::string(arr)).size() << endl;
kout << "(bse::string)arr (" << static_cast<bse::string>(arr) << ") == str2 (" << str2 << "): " << static_cast<int>(bse::string(arr) == str2) << endl;
kout.unlock();
scheduler.exit();
}

View File

@ -1,6 +1,8 @@
#include "kernel/event/KeyEventListener.h"
#include "kernel/system/Globals.h"
namespace Kernel {
void KeyEventListener::trigger(char c) {
lastChar = c;
}
@ -10,3 +12,5 @@ char KeyEventListener::waitForKeyEvent() const {
scheduler.block();
return lastChar; // This is only executed after thread is woken up by manager
}
}

View File

@ -3,15 +3,18 @@
#include "kernel/process/Thread.h"
namespace Kernel {
class KeyEventListener {
private:
char lastChar = '\0';
friend class KeyEventManager;
unsigned int tid; // Thread which contains this listener, so the listener can block the thread
public:
KeyEventListener(const KeyEventListener& copy) = delete;
KeyEventListener(const KeyEventListener &copy) = delete;
KeyEventListener(unsigned int tid) : tid(tid) {}
@ -19,4 +22,6 @@ public:
void trigger(char c); // Gets called from KeyEventManager
};
}
#endif

View File

@ -1,14 +1,16 @@
#include "KeyEventManager.h"
#include "kernel/system/Globals.h"
void KeyEventManager::subscribe(KeyEventListener& sub) {
namespace Kernel {
void KeyEventManager::subscribe(KeyEventListener &sub) {
log.debug() << "Subscribe, Thread ID: " << dec << sub.tid << endl;
listeners.push_back(&sub);
}
void KeyEventManager::unsubscribe(KeyEventListener& unsub) {
void KeyEventManager::unsubscribe(KeyEventListener &unsub) {
log.debug() << "Unsubscribe, Thread ID: " << dec << unsub.tid << endl;
for (bse::vector<KeyEventListener*>::iterator it = listeners.begin(); it != listeners.end(); ++it) {
for (Container::vector<KeyEventListener *>::iterator it = listeners.begin(); it != listeners.end(); ++it) {
if ((*it)->tid == unsub.tid) {
listeners.erase(it);
return;
@ -18,9 +20,11 @@ void KeyEventManager::unsubscribe(KeyEventListener& unsub) {
void KeyEventManager::broadcast(char c) {
log.trace() << "Beginning Broadcast" << endl;
for (KeyEventListener* listener : listeners) {
for (KeyEventListener *listener: listeners) {
log.trace() << "Broadcasting " << c << " to Thread ID: " << dec << listener->tid << endl;
listener->trigger(c);
scheduler.deblock(listener->tid);
}
}
}

View File

@ -2,20 +2,22 @@
#define KeyEventManager_Include_H_
#include "kernel/event/KeyEventListener.h"
#include "kernel/log/Logger.h"
#include "lib/util/Vector.h"
#include "lib/stream/Logger.h"
#include "lib/container/Vector.h"
// NOTE: Could do this more generally but we only have key events
// Also pretty limited: One thread can have one listener as identification is done over tid
namespace Kernel {
class KeyEventManager {
private:
NamedLogger log;
bse::vector<KeyEventListener*> listeners;
Container::vector<KeyEventListener *> listeners;
public:
KeyEventManager(const KeyEventManager& copy) = delete;
KeyEventManager(const KeyEventManager &copy) = delete;
KeyEventManager() : log("KEvMan"), listeners(true) {}
@ -23,9 +25,13 @@ public:
listeners.reserve();
}
void subscribe(KeyEventListener& sub);
void unsubscribe(KeyEventListener& unsub);
void subscribe(KeyEventListener &sub);
void unsubscribe(KeyEventListener &unsub);
void broadcast(char c); // Unblocks all input waiting threads, I don't have a method to direct input
};
}
#endif

View File

@ -5,7 +5,7 @@
*---------------------------------------------------------------------------*
* Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. *
* ist der Stack und oder Heap kaputt, weswegen hier nicht *
* kout etc. verwendet wird. *
* Kernel::kout etc. verwendet wird. *
* *
* Autor: Michael Schoettner, 11.12.2018 *
*****************************************************************************/
@ -13,39 +13,39 @@
// in startup.asm
extern "C" {
// CR2 auslesen
uint32_t get_page_fault_address();
// CR2 auslesen
uint32_t get_page_fault_address();
// 1st level interrupt handler in startup.asm sichert Zeiger auf Stackframe
// unmittelbar nach dem Interrupt und nachdem alle Register mit PUSHAD
// gesichert wurden
// |-------------|
// |  EFLAGS |
// |-------------|
// | CS |
// |-------------|
// | EIP |
// |-------------|
// | [ErrorCode] |
// |-------------|
// | EAX |
// |-------------|
// | ECX |
// |-------------|
// | EDX |
// |-------------|
// | EBX |
// |-------------|
// | ESP |
// |-------------|
// | EBP |
// |-------------|
// | ESI |
// |-------------|
// | EDI |
// |-------------| <-- int_esp
// 1st level interrupt handler in startup.asm sichert Zeiger auf Stackframe
// unmittelbar nach dem Interrupt und nachdem alle Register mit PUSHAD
// gesichert wurden
// |-------------|
// |  EFLAGS |
// |-------------|
// | CS |
// |-------------|
// | EIP |
// |-------------|
// | [ErrorCode] |
// |-------------|
// | EAX |
// |-------------|
// | ECX |
// |-------------|
// | EDX |
// |-------------|
// | EBX |
// |-------------|
// | ESP |
// |-------------|
// | EBP |
// |-------------|
// | ESI |
// |-------------|
// | EDI |
// |-------------| <-- int_esp
void get_int_esp(uint32_t** esp);
void get_int_esp(uint32_t **esp);
}
void break_on_bluescreen() {
@ -67,7 +67,7 @@ uint8_t bs_ypos = 0;
void bs_clear() {
uint8_t x;
uint8_t y;
auto* ptr = reinterpret_cast<uint16_t*>(0xb8000);
auto *ptr = reinterpret_cast<uint16_t *>(0xb8000);
for (x = 0; x < 80; x++) {
for (y = 0; y < 25; y++) {
@ -95,7 +95,7 @@ void bs_lf() {
* Beschreibung: Ein Zeichen ausgeben. *
*****************************************************************************/
void bs_print_char(char c) {
auto* ptr = reinterpret_cast<uint8_t*>(0xb8000);
auto *ptr = reinterpret_cast<uint8_t *>(0xb8000);
*(ptr + bs_ypos * 80 * 2 + bs_xpos * 2) = c;
bs_xpos++;
@ -106,7 +106,7 @@ void bs_print_char(char c) {
*---------------------------------------------------------------------------*
* Beschreibung: Eine Zeichenkette ausgeben. *
*****************************************************************************/
void bs_print_string(char* str) {
void bs_print_string(char *str) {
while (*str != '\0') {
bs_print_char(*str);
@ -144,7 +144,7 @@ void bs_print_uintHex(uint32_t c) {
* Beschreibung: String mit Integer ausgeben. Wird verwendet um ein *
* Register auszugeben. *
*****************************************************************************/
void bs_printReg(char* str, uint32_t value) {
void bs_printReg(char *str, uint32_t value) {
bs_print_string(str);
bs_print_uintHex(value);
bs_print_string(" \0");
@ -156,8 +156,8 @@ void bs_printReg(char* str, uint32_t value) {
* Beschreibung: Hauptroutine des Bluescreens. *
*****************************************************************************/
void bs_dump(uint8_t exceptionNr) {
uint32_t* int_esp;
uint32_t* sptr;
uint32_t *int_esp;
uint32_t *sptr;
uint32_t faultAdress;
uint8_t has_error_code = 0;
@ -183,25 +183,62 @@ void bs_dump(uint8_t exceptionNr) {
// Spruch ausgeben
switch (exceptionNr) {
case 0x00: bs_print_string("Divide Error\0"); break;
case 0x01: bs_print_string("Debug Exception\0"); break;
case 0x02: bs_print_string("NMI\0"); break;
case 0x03: bs_print_string("Breakpoint Exception\0"); break;
case 0x04: bs_print_string("Into Exception\0"); break;
case 0x05: bs_print_string("Index out of range Exception\0"); break;
case 0x06: bs_print_string("Invalid Opcode\0"); break;
case 0x08: bs_print_string("Double Fault\0"); break;
case 0x0D: bs_print_string("General Protection Error\0"); break;
case 0x0E: bs_print_string("Page Fault\0"); break;
case 0x18: bs_print_string("Stack invalid\0"); break;
case 0x19: bs_print_string("Return missing\0"); break;
case 0x1A: bs_print_string("Type Test Failed\0"); break;
case 0x1B: bs_print_string("Null pointer exception\0"); break;
case 0x1C: bs_print_string("MAGIC.StackTest failed\0"); break;
case 0x1D: bs_print_string("Memory-Panic\0"); break;
case 0x1E: bs_print_string("Pageload failed\0"); break;
case 0x1F: bs_print_string("Stack overflow\0"); break;
default: bs_print_string("unknown\0");
case 0x00:
bs_print_string("Divide Error\0");
break;
case 0x01:
bs_print_string("Debug Exception\0");
break;
case 0x02:
bs_print_string("NMI\0");
break;
case 0x03:
bs_print_string("Breakpoint Exception\0");
break;
case 0x04:
bs_print_string("Into Exception\0");
break;
case 0x05:
bs_print_string("Index out of range Exception\0");
break;
case 0x06:
bs_print_string("Invalid Opcode\0");
break;
case 0x08:
bs_print_string("Double Fault\0");
break;
case 0x0D:
bs_print_string("General Protection Error\0");
break;
case 0x0E:
bs_print_string("Page Fault\0");
break;
case 0x18:
bs_print_string("Stack invalid\0");
break;
case 0x19:
bs_print_string("Return missing\0");
break;
case 0x1A:
bs_print_string("Type Test Failed\0");
break;
case 0x1B:
bs_print_string("Null pointer exception\0");
break;
case 0x1C:
bs_print_string("MAGIC.StackTest failed\0");
break;
case 0x1D:
bs_print_string("Memory-Panic\0");
break;
case 0x1E:
bs_print_string("Pageload failed\0");
break;
case 0x1F:
bs_print_string("Stack overflow\0");
break;
default:
bs_print_string("unknown\0");
}
bs_print_string(")\0");
bs_lf();
@ -210,7 +247,7 @@ void bs_dump(uint8_t exceptionNr) {
get_int_esp(&int_esp);
// wir müssen den Inhalt auslesen und das als Zeiger verwenden, um den Stack auszulesen
sptr = reinterpret_cast<uint32_t*>(*int_esp);
sptr = reinterpret_cast<uint32_t *>(*int_esp);
bs_lf();
@ -244,7 +281,7 @@ void bs_dump(uint8_t exceptionNr) {
bs_lf();
bs_print_string("Last useable address = \0");
bs_print_uintHex(total_mem - 1);
bs_print_uintHex(Kernel::total_mem - 1);
bs_lf();
}
@ -277,7 +314,7 @@ void bs_dump(uint8_t exceptionNr) {
bs_print_string("Calling Stack:\0");
bs_lf();
int x = 0;
auto* ebp = reinterpret_cast<uint32_t*>(*(sptr + 2));
auto *ebp = reinterpret_cast<uint32_t *>(*(sptr + 2));
uint32_t raddr;
// solange eip > 1 MB && ebp < 128 MB, max. Aufruftiefe 10
@ -288,7 +325,7 @@ void bs_dump(uint8_t exceptionNr) {
bs_lf();
// dynamische Kette -> zum Aufrufer
ebp = reinterpret_cast<uint32_t*>(*ebp);
ebp = reinterpret_cast<uint32_t *>(*ebp);
x++;
}

View File

@ -5,7 +5,7 @@
*---------------------------------------------------------------------------*
* Beschreibung: Ein Bluescreen, falls eine x86 Exception auftritt. Evt. *
* ist der Stack und oder Heap kaputt, weswegen hier nicht *
* kout etc. verwendet wird. *
* Kernel::kout etc. verwendet wird. *
* *
* Autor: Michael Schoettner, 2.2.2017 *
*****************************************************************************/
@ -13,7 +13,10 @@
#ifndef Bluescreen_include__
#define Bluescreen_include__
#include <cstdint>
// dump blue screen (will not return)
void bs_dump(uint8_t exceptionNr);
#endif

View File

@ -12,9 +12,11 @@
#ifndef ISR_include__
#define ISR_include__
namespace Kernel {
class ISR {
public:
ISR(const ISR& copy) = delete; // Verhindere Kopieren
ISR(const ISR &copy) = delete; // Verhindere Kopieren
// virtual ~ISR() = default;
@ -24,4 +26,6 @@ public:
virtual void trigger() = 0;
};
}
#endif

View File

@ -13,7 +13,7 @@
#include "IntDispatcher.h"
#include "device/cpu/CPU.h"
#include "kernel/system/Globals.h"
#include "kernel/interrupt/Bluescreen.h"
#include "kernel/exception//Bluescreen.h"
extern "C" void int_disp(uint8_t vector);
@ -35,16 +35,18 @@ void int_disp(uint8_t vector) {
if (vector < 32) {
bs_dump(vector);
CPU::halt();
Device::CPU::halt();
}
if (intdis.report(vector) < 0) {
kout << "Panic: unexpected interrupt " << vector;
kout << " - processor halted." << endl;
CPU::halt();
if (Kernel::intdis.report(vector) < 0) {
Kernel::kout << "Panic: unexpected interrupt " << vector;
Kernel::kout << " - processor halted." << endl;
Device::CPU::halt();
}
}
namespace Kernel {
/*****************************************************************************
* Methode: IntDispatcher::assign *
*---------------------------------------------------------------------------*
@ -56,7 +58,7 @@ void int_disp(uint8_t vector) {
* *
* Rueckgabewert: 0 = Erfolg, -1 = Fehler *
*****************************************************************************/
int IntDispatcher::assign(uint8_t vector, ISR& isr) {
int IntDispatcher::assign(uint8_t vector, ISR &isr) {
/* hier muss Code eingefuegt werden */
@ -89,7 +91,7 @@ int IntDispatcher::report(uint8_t vector) {
return -1;
}
ISR* isr = map[vector];
ISR *isr = map[vector];
if (isr == nullptr) {
log.error() << "No ISR registered for vector " << vector << endl;
@ -107,3 +109,5 @@ int IntDispatcher::report(uint8_t vector) {
return 0;
}
}

View File

@ -14,18 +14,22 @@
#define IntDispatcher_include__
#include "ISR.h"
#include "lib/util/Array.h"
#include "kernel/log/Logger.h"
#include "lib/container//Array.h"
#include "lib/stream/Logger.h"
namespace Kernel {
class IntDispatcher {
private:
NamedLogger log;
enum { size = 256 };
bse::array<ISR*, size> map;
enum {
size = 256
};
Container::array<ISR *, size> map;
public:
IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren
IntDispatcher(const IntDispatcher &copy) = delete; // Verhindere Kopieren
// Vektor-Nummern
enum {
@ -36,16 +40,18 @@ public:
// Initialisierung der ISR map mit einer Default-ISR.
IntDispatcher() : log("IntDis") {
for (ISR*& slot : map) {
for (ISR *&slot: map) {
slot = nullptr;
}
}
// Registrierung einer ISR. (Rueckgabewert: 0 = Erfolg, -1 = Fehler)
int assign(uint8_t vector, ISR& isr);
int assign(uint8_t vector, ISR &isr);
// ISR fuer 'vector' ausfuehren
int report(uint8_t vector);
};
}
#endif

View File

@ -1,119 +0,0 @@
#include "Logger.h"
#include "kernel/system/Globals.h"
bool Logger::kout_enabled = true;
bool Logger::serial_enabled = true;
Logger::LogLevel Logger::level = Logger::ERROR;
constexpr const char* ansi_red = "\033[1;31m";
constexpr const char* ansi_green = "\033[1;32m";
constexpr const char* ansi_yellow = "\033[1;33m";
constexpr const char* ansi_blue = "\033[1;34m";
constexpr const char* ansi_magenta = "\033[1;35m";
constexpr const char* ansi_cyan = "\033[1;36m";
constexpr const char* ansi_white = "\033[1;37m";
constexpr const char* ansi_default = "\033[0;39m ";
void Logger::log(const bse::string_view message, CGA::color col) const {
if (Logger::kout_enabled) {
CGA::color old_col = kout.color_fg;
kout << fgc(col)
<< "["
<< Logger::level_to_string(current_message_level) << "] "
<< message << fgc(old_col);
kout.flush(); // Don't add newline, Logger already does that
}
if (Logger::serial_enabled) {
switch (col) {
case CGA::WHITE:
SerialOut::write(ansi_white);
break;
case CGA::LIGHT_MAGENTA:
SerialOut::write(ansi_magenta);
break;
case CGA::LIGHT_RED:
SerialOut::write(ansi_red);
break;
case CGA::LIGHT_BLUE:
SerialOut::write(ansi_blue);
break;
default:
SerialOut::write(ansi_default);
}
SerialOut::write("[");
SerialOut::write(Logger::level_to_string(current_message_level));
SerialOut::write("] ");
SerialOut::write(message);
SerialOut::write('\r');
// serial.write("\r\n");
}
}
void Logger::flush() {
buffer[pos] = '\0';
switch (current_message_level) {
case Logger::TRACE:
trace(buffer.data());
break;
case Logger::DEBUG:
debug(buffer.data());
break;
case Logger::ERROR:
error(buffer.data());
break;
case Logger::INFO:
info(buffer.data());
break;
}
current_message_level = Logger::INFO;
pos = 0;
Logger::unlock();
}
void Logger::trace(const bse::string_view message) const {
if (Logger::level <= Logger::TRACE) {
log(message, CGA::WHITE);
}
}
void Logger::debug(const bse::string_view message) const {
if (Logger::level <= Logger::DEBUG) {
log(message, CGA::LIGHT_MAGENTA);
}
}
void Logger::error(const bse::string_view message) const {
if (Logger::level <= Logger::ERROR) {
log(message, CGA::LIGHT_RED);
}
}
void Logger::info(const bse::string_view message) const {
if (Logger::level <= Logger::INFO) {
log(message, CGA::LIGHT_BLUE);
}
}
// Manipulatoren
Logger& TRACE(Logger& log) {
log.current_message_level = Logger::TRACE;
return log;
}
Logger& DEBUG(Logger& log) {
log.current_message_level = Logger::DEBUG;
return log;
}
Logger& ERROR(Logger& log) {
log.current_message_level = Logger::ERROR;
return log;
}
Logger& INFO(Logger& log) {
log.current_message_level = Logger::INFO;
return log;
}

View File

@ -34,6 +34,8 @@
#include "Allocator.h"
#include "kernel/system/Globals.h"
namespace Kernel {
constexpr const unsigned int MEM_SIZE_DEF = 8 * 1024 * 1024; // Groesse des Speichers = 8 MB
constexpr const unsigned int HEAP_START = 0x300000; // Startadresse des Heaps
constexpr const unsigned int HEAP_SIZE = 1024 * 1024; // Default-Groesse des Heaps, falls \
@ -42,39 +44,42 @@ constexpr const unsigned int HEAP_SIZE = 1024 * 1024; // Default-Groesse des He
/*****************************************************************************
* Konstruktor: Allocator::Allocator *
*****************************************************************************/
Allocator::Allocator() : heap_start(HEAP_START), heap_end(HEAP_START + HEAP_SIZE), heap_size(HEAP_SIZE), initialized(1) {
Allocator::Allocator() : heap_start(HEAP_START), heap_end(HEAP_START + HEAP_SIZE), heap_size(HEAP_SIZE),
initialized(1) {
// Groesse des Hauptspeichers (kann über das BIOS abgefragt werden,
// aber sehr umstaendlich, daher hier fest eingetragen
total_mem = MEM_SIZE_DEF;
}
}
/*****************************************************************************
* Nachfolgend sind die Operatoren von C++, die wir hier ueberschreiben *
* und entsprechend 'mm_alloc' und 'mm_free' aufrufen. *
*****************************************************************************/
void* operator new(std::size_t size) {
return allocator.alloc(size);
void *operator new(std::size_t size) {
return Kernel::allocator.alloc(size);
}
void* operator new[](std::size_t count) {
return allocator.alloc(count);
void *operator new[](std::size_t count) {
return Kernel::allocator.alloc(count);
}
void operator delete(void* ptr) {
allocator.free(ptr);
void operator delete(void *ptr) {
Kernel::allocator.free(ptr);
}
void operator delete[](void* ptr) {
allocator.free(ptr);
void operator delete[](void *ptr) {
Kernel::allocator.free(ptr);
}
void operator delete(void* ptr, unsigned int sz) {
allocator.free(ptr);
void operator delete(void *ptr, unsigned int sz) {
Kernel::allocator.free(ptr);
}
// I don't know if accidentally deleted it but one delete was missing
// https://en.cppreference.com/w/cpp/memory/new/operator_delete
void operator delete[](void* ptr, unsigned int sz) {
allocator.free(ptr);
void operator delete[](void *ptr, unsigned int sz) {
Kernel::allocator.free(ptr);
}

View File

@ -33,12 +33,14 @@
#ifndef Allocator_include__
#define Allocator_include__
namespace Kernel {
constexpr const unsigned int BASIC_ALIGN = 4; // 32 Bit so 4 Bytes?
constexpr const unsigned int HEAP_MIN_FREE_BLOCK_SIZE = 64; // min. Groesse eines freien Blocks
class Allocator {
public:
Allocator(Allocator& copy) = delete; // Verhindere Kopieren
Allocator(Allocator &copy) = delete; // Verhindere Kopieren
Allocator();
@ -50,9 +52,14 @@ public:
unsigned int initialized;
virtual void init() = 0;
virtual void dump_free_memory() = 0;
virtual void* alloc(unsigned int req_size) = 0;
virtual void free(void* ptr) = 0;
virtual void *alloc(unsigned int req_size) = 0;
virtual void free(void *ptr) = 0;
};
}
#endif

View File

@ -12,6 +12,8 @@
#include "BumpAllocator.h"
#include "kernel/system/Globals.h"
namespace Kernel {
/*****************************************************************************
* Methode: BumpAllocator::init *
*---------------------------------------------------------------------------*
@ -22,7 +24,7 @@ void BumpAllocator::init() {
/* Hier muess Code eingefuegt werden */
allocations = 0;
next = reinterpret_cast<uint8_t*>(heap_start);
next = reinterpret_cast<uint8_t *>(heap_start);
log.info() << "Initialized Bump Allocator" << endl;
}
@ -36,7 +38,7 @@ void BumpAllocator::dump_free_memory() {
/* Hier muess Code eingefuegt werden */
kout << "Freier Speicher:" << endl
Kernel::kout << "Freier Speicher:" << endl
<< " - Next: " << hex << reinterpret_cast<uint32_t>(next)
<< ", Allocations: " << dec << allocations << endl;
}
@ -46,7 +48,7 @@ void BumpAllocator::dump_free_memory() {
*---------------------------------------------------------------------------*
* Beschreibung: Einen neuen Speicherblock allozieren. *
*****************************************************************************/
void* BumpAllocator::alloc(uint32_t req_size) {
void *BumpAllocator::alloc(uint32_t req_size) {
/* Hier muess Code eingefuegt werden */
@ -57,8 +59,8 @@ void* BumpAllocator::alloc(uint32_t req_size) {
return nullptr;
}
void* allocated = next;
next = reinterpret_cast<uint8_t*>(reinterpret_cast<uint32_t>(next) + req_size);
void *allocated = next;
next = reinterpret_cast<uint8_t *>(reinterpret_cast<uint32_t>(next) + req_size);
allocations = allocations + 1;
log.trace() << " - Allocated " << hex << req_size << " Bytes." << endl;
@ -71,6 +73,8 @@ void* BumpAllocator::alloc(uint32_t req_size) {
*---------------------------------------------------------------------------*
* Beschreibung: Nicht implementiert. *
*****************************************************************************/
void BumpAllocator::free(void* ptr) {
void BumpAllocator::free(void *ptr) {
log.error() << " mm_free: ptr= " << hex << reinterpret_cast<uint32_t>(ptr) << ", not supported" << endl;
}
}

View File

@ -13,26 +13,33 @@
#define BumpAllocator_include__
#include "Allocator.h"
#include "kernel/log/Logger.h"
#include "lib/stream/Logger.h"
namespace Kernel {
class BumpAllocator : Allocator {
private:
uint8_t* next;
uint8_t *next;
uint32_t allocations;
NamedLogger log;
public:
BumpAllocator(Allocator& copy) = delete; // Verhindere Kopieren
BumpAllocator(Allocator &copy) = delete; // Verhindere Kopieren
BumpAllocator() : log("BMP-Alloc") {}; // Allocator() called implicitely in C++
// ~BumpAllocator() override = default;
void init() override;
void dump_free_memory() override;
void* alloc(uint32_t req_size) override;
void free(void* ptr) override;
void *alloc(uint32_t req_size) override;
void free(void *ptr) override;
};
}
#endif

View File

@ -17,6 +17,8 @@
// memory addresses of each block
// (That was the plan at least)
namespace Kernel {
/*****************************************************************************
* Methode: LinkedListAllocator::init *
*---------------------------------------------------------------------------*
@ -31,7 +33,7 @@ void LinkedListAllocator::init() {
/* Hier muess Code eingefuegt werden */
free_start = reinterpret_cast<free_block_t*>(heap_start);
free_start = reinterpret_cast<free_block_t *>(heap_start);
free_start->allocated = false;
free_start->size = heap_size - sizeof(free_block_t);
free_start->next = free_start; // Only one block, points to itself
@ -48,16 +50,16 @@ void LinkedListAllocator::dump_free_memory() {
/* Hier muess Code eingefuegt werden */
kout << "Freier Speicher:" << endl;
Kernel::kout << "Freier Speicher:" << endl;
if (free_start == nullptr) {
kout << " - No free Blocks" << endl;
Kernel::kout << " - No free Blocks" << endl;
} else {
kout << " - Freelist start: " << hex << reinterpret_cast<uint32_t>(free_start) << endl;
Kernel::kout << " - Freelist start: " << hex << reinterpret_cast<uint32_t>(free_start) << endl;
free_block_t* current = free_start;
free_block_t *current = free_start;
do {
kout << " - Free Block (Start: " << hex << reinterpret_cast<uint32_t>(current)
Kernel::kout << " - Free Block (Start: " << hex << reinterpret_cast<uint32_t>(current)
<< " Size: " << hex << current->size << ")" << endl;
current = current->next;
} while (current != free_start);
@ -69,7 +71,7 @@ void LinkedListAllocator::dump_free_memory() {
*---------------------------------------------------------------------------*
* Beschreibung: Einen neuen Speicherblock allozieren. *
*****************************************************************************/
void* LinkedListAllocator::alloc(uint32_t req_size) {
void *LinkedListAllocator::alloc(uint32_t req_size) {
lock.acquire();
/* Hier muess Code eingefuegt werden */
@ -90,7 +92,7 @@ void* LinkedListAllocator::alloc(uint32_t req_size) {
log.trace() << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl;
}
free_block_t* current = free_start;
free_block_t *current = free_start;
do {
if (current->size >= rreq_size) { // Size doesn't contain header, only usable
// Current block large enough
@ -104,8 +106,9 @@ void* LinkedListAllocator::alloc(uint32_t req_size) {
// [<> | current | new_next | <>]
// In case of only one freeblock:
// [current | new_next]
free_block_t* new_next =
reinterpret_cast<free_block_t*>(reinterpret_cast<uint32_t>(current) + sizeof(free_block_t) + rreq_size);
free_block_t *new_next =
reinterpret_cast<free_block_t *>(reinterpret_cast<uint32_t>(current) + sizeof(free_block_t) +
rreq_size);
// If only one block exists, current->next is current
// This shouldn't be a problem since the block gets removed from the list later
@ -138,7 +141,7 @@ void* LinkedListAllocator::alloc(uint32_t req_size) {
// If block was cut this is obvious, because current->next is a free block
// If block wasn't cut it also works as current was a free block before, so it's next
// block should also be free
free_block_t* previous = LinkedListAllocator::find_previous_block(current);
free_block_t *previous = LinkedListAllocator::find_previous_block(current);
previous->next = current->next; // Current block was free so previous block pointed at it
current->allocated = true;
@ -154,9 +157,11 @@ void* LinkedListAllocator::alloc(uint32_t req_size) {
// }
// log.debug() << "Finished check" << endl;
log.debug() << "returning memory address " << hex << reinterpret_cast<uint32_t>(current) + sizeof(free_block_t) << endl;
log.debug() << "returning memory address " << hex
<< reinterpret_cast<uint32_t>(current) + sizeof(free_block_t) << endl;
lock.release();
return reinterpret_cast<void*>(reinterpret_cast<uint32_t>(current) + sizeof(free_block_t)); // Speicheranfang, nicht header
return reinterpret_cast<void *>(reinterpret_cast<uint32_t>(current) +
sizeof(free_block_t)); // Speicheranfang, nicht header
}
current = current->next;
@ -172,13 +177,14 @@ void* LinkedListAllocator::alloc(uint32_t req_size) {
*---------------------------------------------------------------------------*
* Beschreibung: Einen Speicherblock freigeben. *
*****************************************************************************/
void LinkedListAllocator::free(void* ptr) {
void LinkedListAllocator::free(void *ptr) {
lock.acquire();
/* Hier muess Code eingefuegt werden */
// Account for header
free_block_t* block_start = reinterpret_cast<free_block_t*>(reinterpret_cast<uint32_t>(ptr) - sizeof(free_block_t));
free_block_t *block_start = reinterpret_cast<free_block_t *>(reinterpret_cast<uint32_t>(ptr) -
sizeof(free_block_t));
log.debug() << "Freeing " << hex << reinterpret_cast<uint32_t>(ptr) << ", Size: " << block_start->size << endl;
@ -200,18 +206,20 @@ void LinkedListAllocator::free(void* ptr) {
return;
}
free_block_t* next_block =
reinterpret_cast<free_block_t*>(reinterpret_cast<uint32_t>(block_start) + sizeof(free_block_t) + block_start->size);
free_block_t *next_block =
reinterpret_cast<free_block_t *>(reinterpret_cast<uint32_t>(block_start) + sizeof(free_block_t) +
block_start->size);
// Find the next free block, multiple next blocks can be allocated so walk through them
free_block_t* next_free = block_start->next;
free_block_t *next_free = block_start->next;
while (next_free->allocated) {
next_free = next_free->next;
}
free_block_t* previous_free = LinkedListAllocator::find_previous_block(next_free);
free_block_t* previous_free_next =
reinterpret_cast<free_block_t*>(reinterpret_cast<uint32_t>(previous_free) + sizeof(free_block_t) + previous_free->size);
free_block_t *previous_free = LinkedListAllocator::find_previous_block(next_free);
free_block_t *previous_free_next =
reinterpret_cast<free_block_t *>(reinterpret_cast<uint32_t>(previous_free) + sizeof(free_block_t) +
previous_free->size);
// We have: [previous_free | previous_free_next | <> | block_start | next_block | <> | next_free]
// The <> spaces don't have to exist and next_block could be the same as next_free
@ -284,7 +292,8 @@ void LinkedListAllocator::free(void* ptr) {
if (free_start == block_start) {
// block_start is now invalid after merge
log.trace() << " - Moving freelist start to " << hex << reinterpret_cast<unsigned int>(previous_free) << endl;
log.trace() << " - Moving freelist start to " << hex << reinterpret_cast<unsigned int>(previous_free)
<< endl;
free_start = previous_free;
}
}
@ -294,17 +303,19 @@ void LinkedListAllocator::free(void* ptr) {
lock.release();
}
free_block_t* LinkedListAllocator::find_previous_block(free_block_t* next_block) {
free_block_t *LinkedListAllocator::find_previous_block(free_block_t *next_block) {
// Durchlaufe die ganze freispeicherliste bis zum Block der auf next_block zeigt
free_block_t* current = next_block;
free_block_t *current = next_block;
while (current->next != next_block) {
// NOTE: This will get stuck if called on the wrong block
current = current->next;
}
// if (current == next_block) {
// kout << "LinkedListAllocator::find_previous_block returned the input block" << endl;
// Kernel::kout << "LinkedListAllocator::find_previous_block returned the input block" << endl;
// }
return current;
}
}

View File

@ -14,45 +14,52 @@
#include "Allocator.h"
#include "lib/async/SpinLock.h"
#include "kernel/log/Logger.h"
#include "lib/stream/Logger.h"
namespace Kernel {
// Format eines freien Blocks, 4 + 4 + 4 Byte
typedef struct free_block {
bool allocated; // NOTE: I added this to allow easier merging of free blocks:
// When freeing an allocated block, its next-pointer can
// point to another allocated block, the next free block
// can be found by traversing the leading allocated blocks.
// We only need a way to determine when the free block is reached.
// This also means that the whole list has to be traversed
// to merge blocks. Would be faster with doubly linked list.
// When freeing an allocated block, its next-pointer can
// point to another allocated block, the next free block
// can be found by traversing the leading allocated blocks.
// We only need a way to determine when the free block is reached.
// This also means that the whole list has to be traversed
// to merge blocks. Would be faster with doubly linked list.
uint32_t size;
struct free_block* next;
struct free_block *next;
} free_block_t;
class LinkedListAllocator : Allocator {
private:
// freie Bloecke werden verkettet
struct free_block* free_start = nullptr;
struct free_block *free_start = nullptr;
// Traverses the whole list forward till previous block is reached.
// This can only be called on free blocks as allocated blocks
// aren't reachable from the freelist.
static struct free_block* find_previous_block(struct free_block*);
static struct free_block *find_previous_block(struct free_block *);
NamedLogger log;
SpinLock lock;
Async::SpinLock lock;
public:
LinkedListAllocator(Allocator& copy) = delete; // Verhindere Kopieren
LinkedListAllocator(Allocator &copy) = delete; // Verhindere Kopieren
LinkedListAllocator() : log("LL-Alloc") {}
// ~LinkedListAllocator() override = default;
void init() override;
void dump_free_memory() override;
void* alloc(uint32_t req_size) override;
void free(void* ptr) override;
void *alloc(uint32_t req_size) override;
void free(void *ptr) override;
};
}
#endif

View File

@ -50,7 +50,9 @@
*****************************************************************************/
#include "kernel/memory/Paging.h"
#include "kernel/system/Globals.h"
#include "kernel/log/Logger.h"
#include "lib/stream/Logger.h"
namespace Kernel {
// Bits fuer Eintraege in der Page-Table
constexpr const unsigned int PAGE_PRESENT = 0x001;
@ -74,10 +76,10 @@ constexpr const unsigned int LST_ALLOCABLE_PAGE = 0x2FF000;
* Beschreibung: Alloziert eine 4 KB Seite. Allozieren heisst hier *
* lediglich Setzen eines eigenen RESERVED-Bits. *
*****************************************************************************/
uint32_t* pg_alloc_page() {
uint32_t* p_page;
uint32_t *pg_alloc_page() {
uint32_t *p_page;
p_page = reinterpret_cast<uint32_t*>(PAGE_TABLE);
p_page = reinterpret_cast<uint32_t *>(PAGE_TABLE);
// 1. Eintrag ist fuer Null-Pointer-Exception reserviert
// ausserdem liegt die Page-Table an Adresse PAGE_TABLE
@ -87,7 +89,7 @@ uint32_t* pg_alloc_page() {
// pruefe ob Page frei
if (((*p_page) & PAGE_RESERVED) == 0) {
*p_page = (*p_page | PAGE_RESERVED);
return reinterpret_cast<uint32_t*>(i << 12); // Address without flags (Offset 0)
return reinterpret_cast<uint32_t *>(i << 12); // Address without flags (Offset 0)
}
}
return nullptr;
@ -99,11 +101,12 @@ uint32_t* pg_alloc_page() {
* Beschreibung: Schreibschutz fuer die uebergebene Seite aktivieren. *
* Dies fuer das Debugging nuetzlich. *
*****************************************************************************/
void pg_write_protect_page(const uint32_t* p_page) {
void pg_write_protect_page(const uint32_t *p_page) {
/* hier muss Code eingefügt werden */
uint32_t* page = reinterpret_cast<uint32_t*>(PAGE_TABLE) + (reinterpret_cast<uint32_t>(p_page) >> 12); // Pagetable entry
uint32_t *page =
reinterpret_cast<uint32_t *>(PAGE_TABLE) + (reinterpret_cast<uint32_t>(p_page) >> 12); // Pagetable entry
uint32_t mask = PAGE_WRITEABLE; // fill to 32bit
*page = *page & ~mask; // set writable to 0
@ -116,11 +119,12 @@ void pg_write_protect_page(const uint32_t* p_page) {
*---------------------------------------------------------------------------*
* Beschreibung: Seite als ausgelagert markieren. Nur fuer Testzwecke. *
*****************************************************************************/
void pg_notpresent_page(const uint32_t* p_page) {
void pg_notpresent_page(const uint32_t *p_page) {
/* hier muss Code eingefügt werden */
uint32_t* page = reinterpret_cast<uint32_t*>(PAGE_TABLE) + (reinterpret_cast<uint32_t>(p_page) >> 12); // Pagetable entry
uint32_t *page =
reinterpret_cast<uint32_t *>(PAGE_TABLE) + (reinterpret_cast<uint32_t>(p_page) >> 12); // Pagetable entry
uint32_t mask = PAGE_PRESENT;
*page = *page & ~mask; // set present to 0
@ -134,7 +138,7 @@ void pg_notpresent_page(const uint32_t* p_page) {
* Beschreibung: Gibt eine 4 KB Seite frei. Es wird hierbei das RESERVED- *
* Bit geloescht. *
*****************************************************************************/
void pg_free_page(uint32_t* p_page) {
void pg_free_page(uint32_t *p_page) {
uint32_t idx = reinterpret_cast<uint32_t>(p_page) >> 12;
// ausserhalb Page ?
@ -143,7 +147,7 @@ void pg_free_page(uint32_t* p_page) {
}
// Eintrag einlesen und aendern (PAGE_WRITEABLE loeschen)
p_page = reinterpret_cast<uint32_t*>(PAGE_TABLE);
p_page = reinterpret_cast<uint32_t *>(PAGE_TABLE);
p_page += idx;
*p_page = ((idx << 12) | PAGE_WRITEABLE | PAGE_PRESENT);
@ -157,8 +161,8 @@ void pg_free_page(uint32_t* p_page) {
*****************************************************************************/
void pg_init() {
uint32_t i;
uint32_t* p_pdir; // Zeiger auf Page-Directory
uint32_t* p_page; // Zeiger auf einzige Page-Table fuer 4 KB Pages
uint32_t *p_pdir; // Zeiger auf Page-Directory
uint32_t *p_page; // Zeiger auf einzige Page-Table fuer 4 KB Pages
uint32_t num_pages; // Anzahl 4 MB Pages die phys. Adressraum umfassen
// wie viele 4 MB Seiten sollen als 'Present' angelegt werden,
@ -174,7 +178,7 @@ void pg_init() {
//
// Eintrag 0: Zeiger auf 4 KB Page-Table
p_pdir = reinterpret_cast<uint32_t*>(PAGE_DIRECTORY);
p_pdir = reinterpret_cast<uint32_t *>(PAGE_DIRECTORY);
*p_pdir = PAGE_TABLE | PAGE_WRITEABLE | PAGE_PRESENT;
// Eintraege 1-1023: Direktes Mapping (1:1) auf 4 MB Pages (ohne Page-Table)
@ -190,7 +194,7 @@ void pg_init() {
//
// 1. Page-Table
//
p_page = reinterpret_cast<uint32_t*>(PAGE_TABLE);
p_page = reinterpret_cast<uint32_t *>(PAGE_TABLE);
// ersten Eintrag loeschen -> not present, write protected -> Null-Pointer abfangen
*p_page = 0;
@ -209,5 +213,7 @@ void pg_init() {
}
// Paging aktivieren (in startup.asm)
paging_on(reinterpret_cast<uint32_t*>(PAGE_DIRECTORY));
paging_on(reinterpret_cast<uint32_t *>(PAGE_DIRECTORY));
}
}

View File

@ -56,23 +56,27 @@
#include <cstdint>
extern "C" {
void paging_on(uint32_t* p_pdir); // Paging einschalten
void invalidate_tlb_entry(const uint32_t* ptr); // Page in TLB invalid.
void paging_on(uint32_t *p_pdir); // Paging einschalten
void invalidate_tlb_entry(const uint32_t *ptr); // Page in TLB invalid.
}
namespace Kernel {
// ativiert paging
extern void pg_init();
// alloziert eine 4 KB Page
extern uint32_t* pg_alloc_page();
extern uint32_t *pg_alloc_page();
// Schreibschutz auf Seite setzen -> fuer debugging nuetzlich
extern void pg_write_protect_page(const uint32_t* p_page);
extern void pg_write_protect_page(const uint32_t *p_page);
// Present Bit loeschen
extern void pg_notpresent_page(const uint32_t* p_page);
extern void pg_notpresent_page(const uint32_t *p_page);
// gibt eine 4 KB Page frei
extern void pg_free_page(uint32_t* p_page);
extern void pg_free_page(uint32_t *p_page);
}
#endif

View File

@ -1,25 +1,27 @@
#include "TreeAllocator.h"
#include "kernel/system/Globals.h"
namespace Kernel {
void TreeAllocator::init() {
free_start = reinterpret_cast<tree_block_t*>(heap_start);
free_start = reinterpret_cast<tree_block_t *>(heap_start);
free_start->allocated = false;
free_start->left = nullptr;
free_start->right = nullptr;
free_start->parent = nullptr;
free_start->red = false; // The root is always black
free_start->next = reinterpret_cast<list_block_t*>(free_start);
free_start->previous = reinterpret_cast<list_block_t*>(free_start);
free_start->next = reinterpret_cast<list_block_t *>(free_start);
free_start->previous = reinterpret_cast<list_block_t *>(free_start);
log.info() << "Initialized Tree Allocator" << endl;
}
void TreeAllocator::dump_free_memory() {
kout << "Free Memory:" << endl;
list_block_t* current = reinterpret_cast<list_block_t*>(heap_start);
Kernel::kout << "Free Memory:" << endl;
list_block_t *current = reinterpret_cast<list_block_t *>(heap_start);
do {
if (!current->allocated) {
kout << " - Free Block at " << reinterpret_cast<uint32_t>(current) << ", Size: "
Kernel::kout << " - Free Block at " << reinterpret_cast<uint32_t>(current) << ", Size: "
<< reinterpret_cast<uint32_t>(current->next) - reinterpret_cast<uint32_t>(current)
<< endl;
}
@ -27,7 +29,7 @@ void TreeAllocator::dump_free_memory() {
} while (reinterpret_cast<uint32_t>(current) != heap_start);
}
void* TreeAllocator::alloc(uint32_t req_size) {
void *TreeAllocator::alloc(uint32_t req_size) {
log.debug() << "Requested " << dec << req_size << " Bytes" << endl;
// Round to word borders + tree_block size
@ -45,7 +47,7 @@ void* TreeAllocator::alloc(uint32_t req_size) {
}
// Finds smallest block that is large enough
tree_block_t* best_fit = rbt_search_bestfit(rreq_size);
tree_block_t *best_fit = rbt_search_bestfit(rreq_size);
if (best_fit == nullptr) {
log.error() << " - No block found" << endl;
return nullptr;
@ -66,7 +68,7 @@ void* TreeAllocator::alloc(uint32_t req_size) {
tree_block_t dummy;
dummy.allocated = false;
rbt_insert(&dummy); // I use the address of the stack allocated struct because it is
// removed before exiting the function
// removed before exiting the function
rbt_remove(best_fit); // BUG: Can trigger bluescreen
if (size > HEAP_MIN_FREE_BLOCK_SIZE + rreq_size + sizeof(list_block_t)) {
@ -74,8 +76,9 @@ void* TreeAllocator::alloc(uint32_t req_size) {
log.trace() << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl;
// [best_fit_start | sizeof(list_block_t) | rreq_size | new_block_start]
tree_block_t* new_block
= reinterpret_cast<tree_block_t*>(reinterpret_cast<char*>(best_fit) + sizeof(list_block_t) + rreq_size);
tree_block_t *new_block
= reinterpret_cast<tree_block_t *>(reinterpret_cast<char *>(best_fit) + sizeof(list_block_t) +
rreq_size);
new_block->allocated = false;
dll_insert(best_fit, new_block);
rbt_insert(new_block);
@ -90,27 +93,27 @@ void* TreeAllocator::alloc(uint32_t req_size) {
rbt_remove(&dummy);
log.trace() << " - Returned address " << hex
<< reinterpret_cast<uint32_t>(reinterpret_cast<char*>(best_fit) + sizeof(list_block_t))
<< reinterpret_cast<uint32_t>(reinterpret_cast<char *>(best_fit) + sizeof(list_block_t))
<< endl;
return reinterpret_cast<void*>(reinterpret_cast<char*>(best_fit) + sizeof(list_block_t));
return reinterpret_cast<void *>(reinterpret_cast<char *>(best_fit) + sizeof(list_block_t));
}
void TreeAllocator::free(void* ptr) {
void TreeAllocator::free(void *ptr) {
log.info() << "Freeing " << hex << reinterpret_cast<uint32_t>(ptr) << endl;
list_block_t* block = reinterpret_cast<list_block_t*>(reinterpret_cast<char*>(ptr) - sizeof(list_block_t));
list_block_t *block = reinterpret_cast<list_block_t *>(reinterpret_cast<char *>(ptr) - sizeof(list_block_t));
if (!block->allocated) {
// Block already free
return;
}
block->allocated = false; // If the block is merged backwards afterwards this is unnecessary
list_block_t* previous = block->previous;
list_block_t* next = block->next;
list_block_t *previous = block->previous;
list_block_t *next = block->next;
if (next->allocated && previous->allocated) {
// No merge
rbt_insert(reinterpret_cast<tree_block_t*>(block));
rbt_insert(reinterpret_cast<tree_block_t *>(block));
return;
}
@ -125,10 +128,11 @@ void TreeAllocator::free(void* ptr) {
// Remove the next block from all lists as it is now part of our freed block
dll_remove(next);
rbt_remove(reinterpret_cast<tree_block_t*>(next)); // BUG: Bluescreen if next is the only block in the freelist
rbt_remove(
reinterpret_cast<tree_block_t *>(next)); // BUG: Bluescreen if next is the only block in the freelist
if (previous->allocated) {
// Don't insert if removed later because of backward merge
rbt_insert(reinterpret_cast<tree_block_t*>(block));
rbt_insert(reinterpret_cast<tree_block_t *>(block));
}
}
@ -139,15 +143,15 @@ void TreeAllocator::free(void* ptr) {
// Remove the current block from all lists as it is now part of the previous block
// It doesn't have to be removed from rbt as it wasn't in there as it was allocated before
dll_remove(block);
rbt_remove(reinterpret_cast<tree_block_t*>(previous));
rbt_insert(reinterpret_cast<tree_block_t*>(previous)); // Reinsert with new size
rbt_remove(reinterpret_cast<tree_block_t *>(previous));
rbt_insert(reinterpret_cast<tree_block_t *>(previous)); // Reinsert with new size
}
// HACK: Same as when allocating
rbt_remove(&dummy);
}
uint32_t TreeAllocator::get_size(list_block_t* block) const {
uint32_t TreeAllocator::get_size(list_block_t *block) const {
if (block->next == block) {
// Only one block exists
return heap_end - (reinterpret_cast<uint32_t>(block) + sizeof(list_block_t));
@ -155,9 +159,12 @@ uint32_t TreeAllocator::get_size(list_block_t* block) const {
if (reinterpret_cast<uint32_t>(block->next) > reinterpret_cast<unsigned int>(block)) {
// Next block is placed later in memory
return reinterpret_cast<unsigned int>(block->next) - (reinterpret_cast<unsigned int>(block) + sizeof(list_block_t));
return reinterpret_cast<unsigned int>(block->next) -
(reinterpret_cast<unsigned int>(block) + sizeof(list_block_t));
}
// Next block is placed earlier in memory which means block is at memory end
return reinterpret_cast<unsigned int>(heap_end) - (reinterpret_cast<unsigned int>(block) + sizeof(list_block_t));
}
}

View File

@ -2,15 +2,17 @@
#define TreeAllocator_include__
#include "Allocator.h"
#include "kernel/log/Logger.h"
#include "lib/stream/Logger.h"
namespace Kernel {
// I can't imagine that this is fast with all the tree logic?
typedef struct list_block {
// Doubly linked list for every block
bool allocated;
struct list_block* next;
struct list_block* previous;
struct list_block *next;
struct list_block *previous;
} list_block_t;
// The free blocks are organized in a red-black tree to enable fast insertion with best-fit strategy.
@ -22,60 +24,75 @@ typedef struct tree_block {
// Doubly linked list for every block
// Locate this at the beginning so we can just cast to allocated_block_t and overwrite the rbt data
bool allocated;
struct list_block* next;
struct list_block* previous;
struct list_block *next;
struct list_block *previous;
// RB tree for free blocks
struct tree_block* left;
struct tree_block* right;
struct tree_block* parent;
struct tree_block *left;
struct tree_block *right;
struct tree_block *parent;
bool red; // RB tree node color
} tree_block_t;
class TreeAllocator : Allocator {
private:
// Root of the rbt
tree_block_t* free_start;
tree_block_t *free_start;
NamedLogger log;
// Returns the size of the usable memory of a block
uint32_t get_size(list_block_t* block) const;
uint32_t get_size(tree_block_t* block) const { return get_size(reinterpret_cast<list_block_t*>(block)); }
uint32_t get_size(list_block_t *block) const;
void dump_free_memory(tree_block_t* node);
uint32_t get_size(tree_block_t *block) const { return get_size(reinterpret_cast<list_block_t *>(block)); }
void dump_free_memory(tree_block_t *node);
// NOTE: Would be nice to have this stuff somewhere else for general use (scheduling?),
// makes no sense to have this as members. I'll move it later
void rbt_rot_l(tree_block_t* x);
void rbt_rot_r(tree_block_t* x);
void rbt_transplant(tree_block_t* a, tree_block_t* b);
tree_block_t* rbt_minimum(tree_block_t* node);
void rbt_rot_l(tree_block_t *x);
void rbt_insert(tree_block_t* node);
void rbt_fix_insert(tree_block_t* k);
void rbt_remove(tree_block_t* z);
void rbt_fix_remove(tree_block_t* x);
void rbt_rot_r(tree_block_t *x);
tree_block_t* rbt_search_bestfit(tree_block_t* node, uint32_t req_size);
tree_block_t* rbt_search_bestfit(uint32_t req_size) { return rbt_search_bestfit(free_start, req_size); }
void rbt_transplant(tree_block_t *a, tree_block_t *b);
void dll_insert(list_block_t* previous, list_block_t* node);
void dll_insert(tree_block_t* previous, tree_block_t* node) {
dll_insert(reinterpret_cast<list_block_t*>(previous), reinterpret_cast<list_block_t*>(node));
tree_block_t *rbt_minimum(tree_block_t *node);
void rbt_insert(tree_block_t *node);
void rbt_fix_insert(tree_block_t *k);
void rbt_remove(tree_block_t *z);
void rbt_fix_remove(tree_block_t *x);
tree_block_t *rbt_search_bestfit(tree_block_t *node, uint32_t req_size);
tree_block_t *rbt_search_bestfit(uint32_t req_size) { return rbt_search_bestfit(free_start, req_size); }
void dll_insert(list_block_t *previous, list_block_t *node);
void dll_insert(tree_block_t *previous, tree_block_t *node) {
dll_insert(reinterpret_cast<list_block_t *>(previous), reinterpret_cast<list_block_t *>(node));
}
void dll_remove(list_block_t* node);
void dll_remove(list_block_t *node);
public:
TreeAllocator(Allocator& copy) = delete; // Verhindere Kopieren
TreeAllocator(Allocator &copy) = delete; // Verhindere Kopieren
TreeAllocator() : log("RBT-Alloc") {};
// ~TreeAllocator() override = default;
void init() override;
void dump_free_memory() override;
void* alloc(uint32_t req_size) override;
void free(void* ptr) override;
void *alloc(uint32_t req_size) override;
void free(void *ptr) override;
};
}
#endif

View File

@ -2,8 +2,10 @@
// RBT code taken from https://github.com/Bibeknam/algorithmtutorprograms
namespace Kernel {
// START copy from algorithmtutorprograms
void TreeAllocator::rbt_transplant(tree_block_t* a, tree_block_t* b) {
void TreeAllocator::rbt_transplant(tree_block_t *a, tree_block_t *b) {
if (a->parent == nullptr) {
free_start = b;
} else if (a == a->parent->left) {
@ -16,15 +18,15 @@ void TreeAllocator::rbt_transplant(tree_block_t* a, tree_block_t* b) {
// insert the key to the tree in its appropriate position
// and fix the tree
void TreeAllocator::rbt_insert(tree_block_t* node) {
void TreeAllocator::rbt_insert(tree_block_t *node) {
// Ordinary Binary Search Insertion
node->parent = nullptr;
node->left = nullptr;
node->right = nullptr;
node->red = true; // new node must be red
tree_block_t* y = nullptr;
tree_block_t* x = free_start;
tree_block_t *y = nullptr;
tree_block_t *x = free_start;
while (x != nullptr) {
y = x;
@ -61,8 +63,8 @@ void TreeAllocator::rbt_insert(tree_block_t* node) {
}
// fix the red-black tree
void TreeAllocator::rbt_fix_insert(tree_block_t* k) {
tree_block_t* u;
void TreeAllocator::rbt_fix_insert(tree_block_t *k) {
tree_block_t *u;
while (k->parent->red) {
if (k->parent == k->parent->parent->right) {
u = k->parent->parent->left; // uncle
@ -112,8 +114,8 @@ void TreeAllocator::rbt_fix_insert(tree_block_t* k) {
}
// rotate left at node x
void TreeAllocator::rbt_rot_l(tree_block_t* x) {
tree_block_t* y = x->right;
void TreeAllocator::rbt_rot_l(tree_block_t *x) {
tree_block_t *y = x->right;
x->right = y->left;
if (y->left != nullptr) {
y->left->parent = x;
@ -131,8 +133,8 @@ void TreeAllocator::rbt_rot_l(tree_block_t* x) {
}
// rotate right at node x
void TreeAllocator::rbt_rot_r(tree_block_t* x) {
tree_block_t* y = x->left;
void TreeAllocator::rbt_rot_r(tree_block_t *x) {
tree_block_t *y = x->left;
x->left = y->right;
if (y->right != nullptr) {
y->right->parent = x;
@ -150,16 +152,16 @@ void TreeAllocator::rbt_rot_r(tree_block_t* x) {
}
// find the node with the minimum key
tree_block_t* TreeAllocator::rbt_minimum(tree_block_t* node) {
tree_block_t *TreeAllocator::rbt_minimum(tree_block_t *node) {
while (node->left != nullptr) {
node = node->left;
}
return node;
}
void TreeAllocator::rbt_remove(tree_block_t* z) {
tree_block_t* x;
tree_block_t* y;
void TreeAllocator::rbt_remove(tree_block_t *z) {
tree_block_t *x;
tree_block_t *y;
y = z;
bool y_original_red = y->red;
@ -192,8 +194,8 @@ void TreeAllocator::rbt_remove(tree_block_t* z) {
}
// fix the rb tree modified by the delete operation
void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
tree_block_t* s;
void TreeAllocator::rbt_fix_remove(tree_block_t *x) {
tree_block_t *s;
while (x != free_start && !x->red) {
if (x == x->parent->left) {
s = x->parent->right;
@ -262,7 +264,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
// END copy from algorithmtutorprograms
// This is recursive and depends on luck
tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, uint32_t req_size) {
tree_block_t *TreeAllocator::rbt_search_bestfit(tree_block_t *node, uint32_t req_size) {
if (node == nullptr) {
return nullptr;
}
@ -289,14 +291,16 @@ tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, uint32_t req
}
// DLL code
void TreeAllocator::dll_insert(list_block_t* previous, list_block_t* node) {
void TreeAllocator::dll_insert(list_block_t *previous, list_block_t *node) {
previous->next->previous = node;
node->next = previous->next;
node->previous = previous;
previous->next = node;
}
void TreeAllocator::dll_remove(list_block_t* node) {
void TreeAllocator::dll_remove(list_block_t *node) {
node->previous->next = node->next;
node->next->previous = node->previous;
}
}

View File

@ -14,9 +14,11 @@
#include "kernel/system/Globals.h"
#include "Thread.h"
namespace Kernel {
class IdleThread : public Thread {
public:
IdleThread(const Thread& copy) = delete; // Verhindere Kopieren
IdleThread(const Thread &copy) = delete; // Verhindere Kopieren
IdleThread() : Thread("IdleThread") {}
@ -29,10 +31,12 @@ public:
}
while (true) {
// kout << "Idle!" << endl;
// Kernel::kout << "Idle!" << endl;
scheduler.yield();
}
}
};
}
#endif

View File

@ -25,6 +25,8 @@
#include "IdleThread.h"
#include <utility>
namespace Kernel {
constexpr const bool INSANE_TRACE = false;
/*****************************************************************************
@ -35,7 +37,7 @@ constexpr const bool INSANE_TRACE = false;
* Parameter: *
* next Thread der die CPU::erhalten soll. *
*****************************************************************************/
void Scheduler::start(bse::vector<bse::unique_ptr<Thread>>::iterator next) {
void Scheduler::start(Container::vector<Memory::unique_ptr<Thread>>::iterator next) {
active = next;
if (active >= ready_queue.end()) {
active = ready_queue.begin();
@ -47,7 +49,7 @@ void Scheduler::start(bse::vector<bse::unique_ptr<Thread>>::iterator next) {
(*active)->start(); // First dereference the Iterator, then the unique_ptr to get Thread
}
void Scheduler::switch_to(Thread* prev_raw, bse::vector<bse::unique_ptr<Thread>>::iterator next) {
void Scheduler::switch_to(Thread *prev_raw, Container::vector<Memory::unique_ptr<Thread>>::iterator next) {
active = next;
if (active >= ready_queue.end()) {
active = ready_queue.begin();
@ -73,7 +75,7 @@ void Scheduler::schedule() {
// Otherwise preemption will be blocked and nothing will happen if the first threads
// run() function is blocking
ready_queue.push_back(bse::make_unique<IdleThread>());
ready_queue.push_back(Memory::make_unique<IdleThread>());
log.info() << "Starting scheduling: starting thread with id: " << dec << (*(ready_queue.end() - 1))->tid << endl;
start(ready_queue.end() - 1);
}
@ -83,11 +85,11 @@ void Scheduler::schedule() {
*---------------------------------------------------------------------------*
* Beschreibung: Thread in readyQueue eintragen. *
*****************************************************************************/
void Scheduler::ready(bse::unique_ptr<Thread>&& thread) {
CPU::disable_int();
void Scheduler::ready(Memory::unique_ptr<Thread> &&thread) {
Device::CPU::disable_int();
log.debug() << "Adding to ready_queue, ID: " << dec << thread->tid << endl;
ready_queue.push_back(std::move(thread));
CPU::enable_int();
Device::CPU::enable_int();
}
/*****************************************************************************
@ -103,18 +105,18 @@ void Scheduler::exit() {
/* hier muss Code eingefuegt werden */
// Thread-Wechsel durch PIT verhindern
CPU::disable_int();
Device::CPU::disable_int();
if (ready_queue.size() == 1) {
log.error() << "Can't exit last thread, active ID: " << dec << (*active)->tid << endl;
CPU::enable_int();
Device::CPU::enable_int();
return;
}
log.debug() << "Exiting thread, ID: " << dec << (*active)->tid << endl;
start(ready_queue.erase(active)); // erase returns the next iterator after the erased element
// cannot use switch_to here as the previous thread no longer
// exists (was deleted by erase)
// cannot use switch_to here as the previous thread no longer
// exists (was deleted by erase)
// Interrupts werden in Thread_switch in Thread.asm wieder zugelassen
// dispatch kehr nicht zurueck
@ -131,19 +133,19 @@ void Scheduler::exit() {
* Parameter: *
* that Zu terminierender Thread *
*****************************************************************************/
void Scheduler::kill(uint32_t tid, bse::unique_ptr<Thread>* ptr) {
CPU::disable_int();
void Scheduler::kill(uint32_t tid, Memory::unique_ptr<Thread> *ptr) {
Device::CPU::disable_int();
uint32_t prev_tid = (*active)->tid;
// Block queue, can always kill
for (bse::vector<bse::unique_ptr<Thread>>::iterator it = block_queue.begin(); it != block_queue.end(); ++it) {
for (Container::vector<Memory::unique_ptr<Thread>>::iterator it = block_queue.begin(); it != block_queue.end(); ++it) {
if ((*it)->tid == tid) {
// Found thread to kill
if (ptr != nullptr) {
// Move old thread out of queue to return it
uint32_t pos = bse::distance(block_queue.begin(), it);
uint32_t pos = distance(block_queue.begin(), it);
*ptr = std::move(block_queue[pos]); // Return the killed thread
}
@ -151,7 +153,7 @@ void Scheduler::kill(uint32_t tid, bse::unique_ptr<Thread>* ptr) {
block_queue.erase(it);
log.info() << "Killed thread from block_queue with id: " << tid << endl;
CPU::enable_int();
Device::CPU::enable_int();
return;
}
}
@ -159,17 +161,17 @@ void Scheduler::kill(uint32_t tid, bse::unique_ptr<Thread>* ptr) {
// Ready queue, can't kill last one
if (ready_queue.size() == 1) {
log.error() << "Kill: Can't kill last thread in ready_queue with id: " << tid << endl;
CPU::enable_int();
Device::CPU::enable_int();
return;
}
for (bse::vector<bse::unique_ptr<Thread>>::iterator it = ready_queue.begin(); it != ready_queue.end(); ++it) {
for (Container::vector<Memory::unique_ptr<Thread>>::iterator it = ready_queue.begin(); it != ready_queue.end(); ++it) {
if ((*it)->tid == tid) {
// Found thread to kill
if (ptr != nullptr) {
// Move old thread out of queue to return it
uint32_t pos = bse::distance(ready_queue.begin(), it);
uint32_t pos = distance(ready_queue.begin(), it);
*ptr = std::move(ready_queue[pos]); // Return the killed thread
}
@ -185,43 +187,43 @@ void Scheduler::kill(uint32_t tid, bse::unique_ptr<Thread>* ptr) {
ready_queue.erase(it);
log.info() << "Killed thread from ready_queue with id: " << tid << endl;
CPU::enable_int();
Device::CPU::enable_int();
return;
}
}
log.error() << "Kill: Couldn't find thread with id: " << tid << " in ready- or block-queue" << endl;
log.error() << "Mabe it already exited itself?" << endl;
CPU::enable_int();
Device::CPU::enable_int();
}
// TODO: Can't retrive the thread right now because it's not clear when it's finished,
// maybe introduce a exited_queue and get it from there
void Scheduler::nice_kill(uint32_t tid, bse::unique_ptr<Thread>* ptr) {
CPU::disable_int();
void Scheduler::nice_kill(uint32_t tid, Memory::unique_ptr<Thread> *ptr) {
Device::CPU::disable_int();
for (bse::unique_ptr<Thread>& thread : block_queue) {
for (Memory::unique_ptr<Thread> &thread: block_queue) {
if (thread->tid == tid) {
thread->suicide();
log.info() << "Nice killed thread in block_queue with id: " << tid << endl;
deblock(tid);
CPU::enable_int();
Device::CPU::enable_int();
return;
}
}
for (bse::unique_ptr<Thread>& thread : ready_queue) {
for (Memory::unique_ptr<Thread> &thread: ready_queue) {
if (thread->tid == tid) {
thread->suicide();
log.info() << "Nice killed thread in ready_queue with id: " << tid << endl;
CPU::enable_int();
Device::CPU::enable_int();
return;
}
}
log.error() << "Can't nice kill thread (not found) with id: " << tid << endl;
log.error() << "Mabe it already exited itself?" << endl;
CPU::enable_int();
Device::CPU::enable_int();
}
/*****************************************************************************
@ -240,13 +242,13 @@ void Scheduler::yield() {
/* hier muss Code eingefuegt werden */
// Thread-Wechsel durch PIT verhindern
CPU::disable_int();
Device::CPU::disable_int();
if (ready_queue.size() == 1) {
if constexpr (INSANE_TRACE) {
log.trace() << "Skipping yield as no thread is waiting, active ID: " << dec << (*active)->tid << endl;
}
CPU::enable_int();
Device::CPU::enable_int();
return;
}
if constexpr (INSANE_TRACE) {
@ -266,7 +268,7 @@ void Scheduler::preempt() {
/* Hier muss Code eingefuegt werden */
CPU::disable_int();
Device::CPU::disable_int();
yield();
}
@ -284,16 +286,16 @@ void Scheduler::block() {
/* hier muss Code eingefuegt werden */
CPU::disable_int();
Device::CPU::disable_int();
if (ready_queue.size() == 1) {
log.error() << "Can't block last thread, active ID: " << dec << (*active)->tid << endl;
CPU::enable_int();
Device::CPU::enable_int();
return;
}
Thread* prev_raw = (*active).get();
std::size_t pos = bse::distance(ready_queue.begin(), active);
Thread *prev_raw = (*active).get();
std::size_t pos = distance(ready_queue.begin(), active);
block_queue.push_back(std::move(ready_queue[pos]));
if constexpr (INSANE_TRACE) {
@ -318,24 +320,26 @@ void Scheduler::deblock(uint32_t tid) {
/* hier muss Code eingefuegt werden */
CPU::disable_int();
Device::CPU::disable_int();
for (bse::vector<bse::unique_ptr<Thread>>::iterator it = block_queue.begin(); it != block_queue.end(); ++it) {
for (Container::vector<Memory::unique_ptr<Thread>>::iterator it = block_queue.begin(); it != block_queue.end(); ++it) {
if ((*it)->tid == tid) {
// Found thread with correct tid
std::size_t pos = bse::distance(block_queue.begin(), it);
std::size_t pos = distance(block_queue.begin(), it);
ready_queue.insert(active + 1, std::move(block_queue[pos])); // We insert the thread after the active
// thread to prefer deblocked threads
// thread to prefer deblocked threads
block_queue.erase(it);
if constexpr (INSANE_TRACE) {
log.trace() << "Deblocked thread with id: " << tid << endl;
}
CPU::enable_int();
Device::CPU::enable_int();
return;
}
}
log.error() << "Couldn't deblock thread with id: " << tid << endl;
CPU::enable_int();
Device::CPU::enable_int();
}
}

View File

@ -14,36 +14,39 @@
#include "Thread.h"
#include "lib/mem/UniquePointer.h"
#include "kernel/log/Logger.h"
#include "lib/util/Vector.h"
#include "lib/stream/Logger.h"
#include "lib/container/Vector.h"
namespace Kernel {
class Scheduler {
private:
NamedLogger log;
bse::vector<bse::unique_ptr<Thread>> ready_queue;
bse::vector<bse::unique_ptr<Thread>> block_queue;
Container::vector<Memory::unique_ptr<Thread>> ready_queue;
Container::vector<Memory::unique_ptr<Thread>> block_queue;
// NOTE: It makes sense to keep track of the active thread through this as it makes handling the
// unique_ptr easier and reduces the copying in the vector when cycling through the threads
bse::vector<bse::unique_ptr<Thread>>::iterator active = nullptr;
Container::vector<Memory::unique_ptr<Thread>>::iterator active = nullptr;
// Scheduler wird evt. von einer Unterbrechung vom Zeitgeber gerufen,
// bevor er initialisiert wurde
uint32_t idle_tid = 0U;
// Roughly the old dispatcher functionality
void start(bse::vector<bse::unique_ptr<Thread>>::iterator next); // Start next without prev
void switch_to(Thread* prev_raw, bse::vector<bse::unique_ptr<Thread>>::iterator next); // Switch from prev to next
void start(Container::vector<Memory::unique_ptr<Thread>>::iterator next); // Start next without prev
void switch_to(Thread *prev_raw, Container::vector<Memory::unique_ptr<Thread>>::iterator next); // Switch from prev to next
// Kann nur vom Idle-Thread aufgerufen werden (erster Thread der vom Scheduler gestartet wird)
void enable_preemption(uint32_t tid) { idle_tid = tid; }
friend class IdleThread;
void ready(bse::unique_ptr<Thread>&& thread);
void ready(Memory::unique_ptr<Thread> &&thread);
public:
Scheduler(const Scheduler& copy) = delete; // Verhindere Kopieren
Scheduler(const Scheduler &copy) = delete; // Verhindere Kopieren
Scheduler() : log("SCHED"), ready_queue(true), block_queue(true) {} // lazy queues, wait for allocator
@ -68,7 +71,7 @@ public:
// Helper that directly constructs the thread, then readys it
template<typename T, typename... Args>
uint32_t ready(Args... args) {
bse::unique_ptr<Thread> thread = bse::make_unique<T>(std::forward<Args>(args)...);
Memory::unique_ptr<Thread> thread = Memory::make_unique<T>(std::forward<Args>(args)...);
uint32_t tid = thread->tid;
ready(std::move(thread));
@ -83,14 +86,16 @@ public:
void exit(); // Returns on error because we don't have exceptions
// Thread mit 'Gewalt' terminieren
void kill(uint32_t tid, bse::unique_ptr<Thread>* ptr);
void kill(uint32_t tid, Memory::unique_ptr<Thread> *ptr);
void kill(uint32_t tid) { kill(tid, nullptr); }
// Asks thread to exit
// NOTE: I had many problems with killing threads that were stuck in some semaphore
// or were involved in any locking mechanisms, so with this a thread can make sure
// to "set things right" before exiting itself (but could also be ignored)
void nice_kill(uint32_t tid, bse::unique_ptr<Thread>* ptr);
void nice_kill(uint32_t tid, Memory::unique_ptr<Thread> *ptr);
void nice_kill(uint32_t tid) { nice_kill(tid, nullptr); }
// CPU freiwillig abgeben und Auswahl des naechsten Threads
@ -106,4 +111,6 @@ public:
void deblock(uint32_t tid);
};
}
#endif

View File

@ -26,13 +26,15 @@
// extern "C" deklariert werden, da sie nicht dem Name-Mangeling von C++
// entsprechen.
extern "C" {
void Thread_start(uint32_t esp);
void Thread_start(uint32_t esp);
// NOTE: Only when backing up the previous thread the esp gets updated,
// so only esp_pre is a pointer
void Thread_switch(uint32_t* esp_prev, uint32_t esp_next);
// NOTE: Only when backing up the previous thread the esp gets updated,
// so only esp_pre is a pointer
void Thread_switch(uint32_t *esp_prev, uint32_t esp_next);
}
namespace Kernel {
uint32_t ThreadCnt = 1; // Skip tid 0 as the scheduler indicates no preemption with 0
/*****************************************************************************
@ -41,7 +43,7 @@ uint32_t ThreadCnt = 1; // Skip tid 0 as the scheduler indicates no preemption
* Beschreibung: Bereitet den Kontext der Koroutine fuer den ersten *
* Aufruf vor. *
*****************************************************************************/
void Thread_init(uint32_t* esp, uint32_t* stack, void (*kickoff)(Thread*), void* object) {
void Thread_init(uint32_t *esp, uint32_t *stack, void (*kickoff)(Thread *), void *object) {
// NOTE: c++17 doesn't allow register
// register uint32_t** sp = (uint32_t**)stack;
@ -82,7 +84,7 @@ void Thread_init(uint32_t* esp, uint32_t* stack, void (*kickoff)(Thread*), void*
* wuerde ein sinnloser Wert als Ruecksprungadresse *
* interpretiert werden und der Rechner abstuerzen. *
*****************************************************************************/
[[noreturn]] void kickoff(Thread* object) {
[[noreturn]] void kickoff(Thread *object) {
object->run();
// object->run() kehrt (hoffentlich) nie hierher zurueck
@ -97,7 +99,7 @@ void Thread_init(uint32_t* esp, uint32_t* stack, void (*kickoff)(Thread*), void*
* Parameter: *
* stack Stack für die neue Koroutine *
*****************************************************************************/
Thread::Thread(char* name) : stack(new uint32_t[1024]), esp(0), log(name), name(name), tid(ThreadCnt++) {
Thread::Thread(char *name) : stack(new uint32_t[1024]), esp(0), log(name), name(name), tid(ThreadCnt++) {
if (stack == nullptr) {
log.error() << "Couldn't initialize Thread (couldn't alloc stack)" << endl;
return;
@ -112,7 +114,7 @@ Thread::Thread(char* name) : stack(new uint32_t[1024]), esp(0), log(name), name(
*---------------------------------------------------------------------------*
* Beschreibung: Auf die nächste Koroutine umschalten. *
*****************************************************************************/
void Thread::switchTo(Thread& next) {
void Thread::switchTo(Thread &next) {
/* hier muss Code eingefügt werden */
@ -131,3 +133,5 @@ void Thread::start() const {
Thread_start(esp);
}
}

View File

@ -28,25 +28,27 @@
#ifndef Thread_include__
#define Thread_include__
#include "kernel/log/Logger.h"
#include "lib/stream/Logger.h"
namespace Kernel {
class Thread {
private:
uint32_t* stack;
uint32_t *stack;
uint32_t esp;
protected:
Thread(char* name);
Thread(char *name);
NamedLogger log;
bool running = true; // For soft exit, if thread uses infinite loop inside run(), use this as condition
char* name; // For logging
char *name; // For logging
uint32_t tid; // Thread-ID (wird im Konstruktor vergeben)
friend class Scheduler; // Scheduler can access tid
public:
Thread(const Thread& copy) = delete; // Verhindere Kopieren
Thread(const Thread &copy) = delete; // Verhindere Kopieren
virtual ~Thread() {
log.info() << "Uninitialized thread, ID: " << dec << tid << " (" << name << ")" << endl;
@ -57,7 +59,7 @@ public:
void start() const;
// Umschalten auf Thread 'next'
void switchTo(Thread& next);
void switchTo(Thread &next);
// Ask thread to terminate itself
void suicide() { running = false; }
@ -66,4 +68,6 @@ public:
virtual void run() = 0;
};
}
#endif

View File

@ -10,15 +10,17 @@
#include "Globals.h"
CGA_Stream kout; // Ausgabe-Strom fuer Kernel
const BIOS& bios = BIOS::instance(); // Schnittstelle zum 16-Bit BIOS
VESA vesa; // VESA-Treiber
namespace Kernel {
PIC pic; // Interrupt-Controller
CGA_Stream kout; // Ausgabe-Strom fuer Kernel
const Device::BIOS &bios = Device::BIOS::instance(); // Schnittstelle zum 16-Bit BIOS
Device::VESA vesa; // VESA-Treiber
Device::PIC pic; // Interrupt-Controller
IntDispatcher intdis; // Unterbrechungsverteilung
PIT pit(10000); // 10000
PCSPK pcspk; // PC-Lautsprecher
Keyboard kb; // Tastatur
Device::PIT pit(10000); // 10000
Device::PCSPK pcspk; // PC-Lautsprecher
Device::Keyboard kb; // Tastatur
// BumpAllocator allocator;
LinkedListAllocator allocator;
@ -27,7 +29,9 @@ LinkedListAllocator allocator;
Scheduler scheduler;
KeyEventManager kevman;
SerialOut serial;
Device::SerialOut serial;
unsigned int total_mem; // RAM total
uint64_t systime = 0;
}

View File

@ -10,7 +10,7 @@
#ifndef Globals_include__
#define Globals_include__
#include "device/graphics/CGA_Stream.h"
#include "lib/stream/CGA_Stream.h"
#include "device/hid/Keyboard.h"
#include "device/sound/PCSPK.h"
#include "device/time/PIT.h"
@ -27,17 +27,19 @@
#include "device/port/SerialOut.h"
#include "kernel/event/KeyEventManager.h"
namespace Kernel {
// I wanted to make more of these singletons but there were problems with atexit missing because of nostdlib I guess
extern CGA_Stream kout; // Ausgabe-Strom fuer Kernel
extern const BIOS& bios; // Schnittstelle zum 16-Bit BIOS
extern VESA vesa; // VESA-Treiber
extern const Device::BIOS &bios; // Schnittstelle zum 16-Bit BIOS
extern Device::VESA vesa; // VESA-Treiber
extern PIC pic; // Interrupt-Controller
extern Device::PIC pic; // Interrupt-Controller
extern IntDispatcher intdis; // Unterbrechungsverteilung
extern PIT pit; // Zeitgeber
extern PCSPK pcspk; // PC-Lautsprecher
extern Keyboard kb; // Tastatur
extern Device::PIT pit; // Zeitgeber
extern Device::PCSPK pcspk; // PC-Lautsprecher
extern Device::Keyboard kb; // Tastatur
// extern BumpAllocator allocator;
extern LinkedListAllocator allocator;
@ -46,9 +48,11 @@ extern LinkedListAllocator allocator;
extern Scheduler scheduler;
extern KeyEventManager kevman;
extern SerialOut serial;
extern Device::SerialOut serial;
extern uint32_t total_mem; // RAM total
extern uint64_t systime; // wird all 10ms hochgezaehlt
}
#endif

View File

@ -1,6 +1,8 @@
#include "Semaphore.h"
#include "kernel/system/Globals.h"
namespace Async {
void Semaphore::p() {
// Lock to allow deterministic operations on counter/queue
lock.acquire();
@ -14,11 +16,11 @@ void Semaphore::p() {
if (!wait_queue.initialized()) { // TODO: I will replace this suboptimal datastructure in the future
wait_queue.reserve();
}
wait_queue.push_back(scheduler.get_active());
wait_queue.push_back(Kernel::scheduler.get_active());
CPU::disable_int(); // Make sure the block() comes through after releasing the lock
Device::CPU::disable_int(); // Make sure the block() comes through after releasing the lock
lock.release();
scheduler.block(); // Moves to next thread, enables int
Kernel::scheduler.block(); // Moves to next thread, enables int
}
}
@ -30,12 +32,14 @@ void Semaphore::v() {
unsigned int tid = wait_queue.front();
wait_queue.erase(wait_queue.begin());
CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock
Device::CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock
lock.release();
scheduler.deblock(tid); // Enables int
Kernel::scheduler.deblock(tid); // Enables int
} else {
// No more threads want to work so free semaphore
counter = counter + 1;
lock.release();
}
}
}

View File

@ -13,18 +13,20 @@
#include "kernel/process/Thread.h"
#include "SpinLock.h"
#include "lib/util/Vector.h"
#include "lib/container//Vector.h"
namespace Async {
class Semaphore {
private:
// Queue fuer wartende Threads.
bse::vector<unsigned int> wait_queue;
Container::vector<unsigned int> wait_queue;
SpinLock lock;
int counter;
public:
Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren
Semaphore(const Semaphore &copy) = delete; // Verhindere Kopieren
// Konstruktor: Initialisieren des Semaphorzaehlers
Semaphore(int c) : wait_queue(true), counter(c) {}
@ -36,4 +38,6 @@ public:
void v();
};
}
#endif

View File

@ -11,6 +11,8 @@
#include "SpinLock.h"
namespace Async {
/*****************************************************************************
* Methode: CAS *
*---------------------------------------------------------------------------*
@ -23,7 +25,7 @@
* *ptr := _new *
* return prev *
*****************************************************************************/
static inline uint32_t CAS(const uint32_t* ptr) {
static inline uint32_t CAS(const uint32_t *ptr) {
uint32_t prev;
/*
@ -35,10 +37,10 @@ static inline uint32_t CAS(const uint32_t* ptr) {
*/
asm volatile("lock;" // prevent race conditions with other cores
"cmpxchg %1, %2;" // %1 = _new; %2 = *ptr
// constraints
: "=a"(prev) // output: =a: RAX -> prev (%0))
: "r"(1), "m"(*ptr), "a"(0) // input = %1, %2, %3 (r=register, m=memory, a=accumlator = eax
: "memory"); // ensures assembly block will not be moved by gcc
// constraints
: "=a"(prev) // output: =a: RAX -> prev (%0))
: "r"(1), "m"(*ptr), "a"(0) // input = %1, %2, %3 (r=register, m=memory, a=accumlator = eax
: "memory"); // ensures assembly block will not be moved by gcc
return prev; // return pointer instead of prev to prevent unnecessary second call
}
@ -62,3 +64,5 @@ void SpinLock::acquire() {
void SpinLock::release() {
lock = 0;
}
}

View File

@ -14,13 +14,15 @@
#include <cstdint>
namespace Async {
class SpinLock {
private:
uint32_t lock;
uint32_t* ptr;
uint32_t *ptr;
public:
SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren
SpinLock(const SpinLock &copy) = delete; // Verhindere Kopieren
SpinLock() : lock(0), ptr(&lock) {}
@ -29,4 +31,6 @@ public:
void release();
};
}
#endif

View File

@ -4,7 +4,7 @@
#include "Iterator.h"
#include <utility>
namespace bse {
namespace Container {
template<typename T, const std::size_t N>
class array {

View File

@ -1,7 +1,7 @@
#ifndef Iterator_Include_H_
#define Iterator_Include_H_
namespace bse {
namespace Container {
// This iterator works for structures where the elements are adjacent in memory.
template<typename T>

View File

@ -4,7 +4,7 @@
#include "Iterator.h"
#include <utility>
namespace bse {
namespace Container {
// 0 is unchecked
template<typename T, std::size_t N = 0>

View File

@ -9,7 +9,7 @@
#include <utility>
// https://en.cppreference.com/w/cpp/container/vector
namespace bse {
namespace Container {
template<typename T>
class vector {

40
src/lib/demo/ArrayDemo.cc Normal file
View File

@ -0,0 +1,40 @@
#include "ArrayDemo.h"
void ArrayDemo::run() {
Container::array<int, 10> arr1 {};
Container::array<int, 10> arr2 {};
Kernel::kout.lock();
Kernel::kout.clear();
Kernel::kout << "Adding..." << endl;
for (int i = 0; i < 10; ++i) {
arr1[i] = i;
}
Kernel::kout << "Iterator printing arr1:" << endl;
for (int i : arr1) {
Kernel::kout << i << " ";
}
Kernel::kout << endl;
Kernel::kout << "Swapping arr1 and arr2..." << endl;
arr1.swap(arr2);
Kernel::kout << "Iterator printing arr1:" << endl;
for (int i : arr1) {
Kernel::kout << i << " ";
}
Kernel::kout << endl;
Kernel::kout << "Iterator printing arr2:" << endl;
for (int i : arr2) {
Kernel::kout << i << " ";
}
Kernel::kout << endl;
// arr1.swap(arr3); // Not possible as type/size has to match
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -2,9 +2,9 @@
#define ArrayDemo_include__
#include "kernel/system/Globals.h"
#include "lib/util/Array.h"
#include "lib/container/Array.h"
class ArrayDemo : public Thread {
class ArrayDemo : public Kernel::Thread {
public:
ArrayDemo(const ArrayDemo& copy) = delete;

View File

@ -11,35 +11,35 @@
#include "HeapDemo.h"
void HeapDemo::run() {
kout.lock();
kout.clear();
kout << "HEAP_DEMO ===================================================================" << endl;
Kernel::kout.lock();
Kernel::kout.clear();
Kernel::kout << "HEAP_DEMO ===================================================================" << endl;
/* hier muss Code eingefuegt werden */
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
// Rounding to word border
kout << "ROUNDING ====================================================================" << endl;
void* alloc = allocator.alloc(1); // 1 Byte
allocator.dump_free_memory();
allocator.free(alloc);
allocator.dump_free_memory();
Kernel::kout << "ROUNDING ====================================================================" << endl;
void* alloc = Kernel::allocator.alloc(1); // 1 Byte
Kernel::allocator.dump_free_memory();
Kernel::allocator.free(alloc);
Kernel::allocator.dump_free_memory();
// Some objects and forward/backward merging
kout << "SOME OBJECTS ================================================================" << endl;
Kernel::kout << "SOME OBJECTS ================================================================" << endl;
MyObj* a = new MyObj(5);
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
MyObj* b = new MyObj(10);
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
MyObj* c = new MyObj(15);
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
delete b; // No merge
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
delete a; // Merge forward BUG: Bluescreen
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
delete c;
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
// Allocate too whole heap
// void* ptr = allocator.alloc(1024 * 1024 - 24);
@ -48,9 +48,9 @@ void HeapDemo::run() {
// allocator.dump_free_memory();
// Allocate too much
kout << "TOO MUCH ====================================================================" << endl;
allocator.alloc(1024 * 1024); // should fail as only 1024 * 1024 - Headersize bytes are available
allocator.dump_free_memory();
Kernel::kout << "TOO MUCH ====================================================================" << endl;
Kernel::allocator.alloc(1024 * 1024); // should fail as only 1024 * 1024 - Headersize bytes are available
Kernel::allocator.dump_free_memory();
// A lot of allocations
// MyObj* objs[1024];
@ -65,14 +65,14 @@ void HeapDemo::run() {
// allocator.dump_free_memory();
// Array allocation
kout << "ARRAY =======================================================================" << endl;
Kernel::kout << "ARRAY =======================================================================" << endl;
MyObj* objs = new MyObj[1024];
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
delete[] objs;
allocator.dump_free_memory();
Kernel::allocator.dump_free_memory();
kout << "HEAP_DEMO END ===============================================================" << endl;
Kernel::kout << "HEAP_DEMO END ===============================================================" << endl;
kout.unlock();
scheduler.exit();
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -20,7 +20,7 @@ public:
const unsigned int value;
};
class HeapDemo : public Thread {
class HeapDemo : public Kernel::Thread {
public:
HeapDemo(const HeapDemo& copy) = delete;

View File

@ -14,21 +14,21 @@ void KeyboardDemo::run() {
/* Hier muess Code eingefuegt werden */
kout << "Keyboard Demo: " << endl;
Kernel::kout << "Keyboard Demo: " << endl;
kout.lock();
kout.clear();
kout << "Info: Die Keyboard Demo sperrt den Output Stream:\n"
Kernel::kout.lock();
Kernel::kout.clear();
Kernel::kout << "Info: Die Keyboard Demo sperrt den Output Stream:\n"
<< " Wenn die Preemption Demo laeuft wird diese also erst\n"
<< " fortfahren wenn die Keyboard Demo wieder beendet ist." << endl;
kout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nInput: ";
kout.flush();
Kernel::kout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nInput: ";
Kernel::kout.flush();
while (running) {
kout << listener.waitForKeyEvent();
kout.flush();
Kernel::kout << listener.waitForKeyEvent();
Kernel::kout.flush();
}
kout.unlock();
scheduler.exit();
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -15,27 +15,27 @@
#include "kernel/process/Thread.h"
#include "kernel/event/KeyEventListener.h"
class KeyboardDemo : public Thread {
class KeyboardDemo : public Kernel::Thread {
private:
KeyEventListener listener;
Kernel::KeyEventListener listener;
public:
KeyboardDemo(const KeyboardDemo& copy) = delete;
KeyboardDemo() : Thread("KeyboardDemo"), listener(tid) {
kevman.subscribe(listener);
Kernel::kevman.subscribe(listener);
}
// Base class destructor will be called automatically
~KeyboardDemo() override {
if (running) {
// NOTE: If the thread was exited nicely it can unlock before destructor,
// but on forced kill kout has to be unlocked in the destructor.
// but on forced kill Kernel::kout has to be unlocked in the destructor.
// This is bad since it could release the lock although some other
// thread set it (so use nice_kill)
kout.unlock();
Kernel::kout.unlock();
}
kevman.unsubscribe(listener);
Kernel::kevman.unsubscribe(listener);
}
void run() override;

View File

@ -12,9 +12,9 @@
#include "VectorDemo.h"
void print_demo_menu() {
kout.lock();
kout.clear();
kout << "Demo Menu, press number to start, k/K to kill:\n"
Kernel::kout.lock();
Kernel::kout.clear();
Kernel::kout << "Demo Menu, press number to start, k/K to kill:\n"
<< "1 - Text Demo\n"
<< "2 - PCSPK Demo\n"
<< "3 - Keyboard Demo\n"
@ -28,7 +28,7 @@ void print_demo_menu() {
<< "0 - bse::unique_ptr demo\n"
<< "! - bse::string demo\n"
<< endl;
kout.unlock();
Kernel::kout.unlock();
}
void MainMenu::run() {
@ -42,49 +42,49 @@ void MainMenu::run() {
if ((input >= '0' && input <= '9') || input == '!') {
switch (input) {
case '1':
running_demo = scheduler.ready<TextDemo>();
running_demo = Kernel::scheduler.ready<TextDemo>();
break;
case '2':
running_demo = scheduler.ready<PCSPKdemo>(&PCSPK::aerodynamic);
running_demo = Kernel::scheduler.ready<PCSPKdemo>(&Device::PCSPK::aerodynamic);
break;
case '3':
running_demo = scheduler.ready<KeyboardDemo>();
running_demo = Kernel::scheduler.ready<KeyboardDemo>();
break;
case '4':
running_demo = scheduler.ready<HeapDemo>();
running_demo = Kernel::scheduler.ready<HeapDemo>();
break;
case '5':
running_demo = scheduler.ready<VBEdemo>();
running_demo = Kernel::scheduler.ready<VBEdemo>();
break;
case '6':
running_demo = scheduler.ready<PagingDemo>();
running_demo = Kernel::scheduler.ready<PagingDemo>();
break;
case '7':
running_demo = scheduler.ready<PreemptiveThreadDemo>(3);
running_demo = Kernel::scheduler.ready<PreemptiveThreadDemo>(3);
break;
case '8':
running_demo = scheduler.ready<VectorDemo>();
running_demo = Kernel::scheduler.ready<VectorDemo>();
break;
case '9':
running_demo = scheduler.ready<ArrayDemo>();
running_demo = Kernel::scheduler.ready<ArrayDemo>();
break;
case '0':
running_demo = scheduler.ready<SmartPointerDemo>();
running_demo = Kernel::scheduler.ready<SmartPointerDemo>();
break;
case '!':
running_demo = scheduler.ready<StringDemo>();
running_demo = Kernel::scheduler.ready<StringDemo>();
break;
}
} else if (input == 'k') {
scheduler.nice_kill(running_demo); // NOTE: If thread exits itself this will throw error
Kernel::scheduler.nice_kill(running_demo); // NOTE: If thread exits itself this will throw error
print_demo_menu();
} else if (input == 'K') {
scheduler.kill(running_demo);
Kernel::scheduler.kill(running_demo);
print_demo_menu();
}
}
scheduler.exit();
Kernel::scheduler.exit();
// This thread won't be deleted...
}

View File

@ -5,19 +5,19 @@
#include "kernel/process/Thread.h"
#include "kernel/event/KeyEventListener.h"
class MainMenu : public Thread {
class MainMenu : public Kernel::Thread {
private:
KeyEventListener listener;
Kernel::KeyEventListener listener;
public:
MainMenu(const MainMenu& copy) = delete;
MainMenu() : Thread("MainMenu"), listener(tid) {
kevman.subscribe(listener);
Kernel::kevman.subscribe(listener);
}
~MainMenu() override {
kevman.unsubscribe(listener);
Kernel::kevman.unsubscribe(listener);
}
void run() override;

16
src/lib/demo/PCSPKdemo.cc Normal file
View File

@ -0,0 +1,16 @@
#include "PCSPKdemo.h"
void PCSPKdemo::run() {
Kernel::kout.lock();
Kernel::kout.clear();
Kernel::kout << "Playing..." << endl;
Kernel::kout.unlock();
(*melody)(); // This syntax is confusing as hell
Kernel::kout.lock();
Kernel::kout << "Finished" << endl;
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -4,7 +4,7 @@
#include "kernel/system/Globals.h"
#include "kernel/process/Thread.h"
class PCSPKdemo : public Thread {
class PCSPKdemo : public Kernel::Thread {
private:
void (*melody)(); // Allow to pass a melody to play when initializing the demo
@ -14,7 +14,7 @@ public:
PCSPKdemo(void (*melody)()) : Thread("PCSPKdemo"), melody(melody) {}
~PCSPKdemo() override {
PCSPK::off();
Device::PCSPK::off();
}
void run() override;

View File

@ -1,17 +1,17 @@
#include "PagingDemo.h"
void PagingDemo::writeprotect_page() {
kout << "Accessing a writeprotected page triggers bluescreen,\nif you can read this it didn't work" << endl;
Kernel::kout << "Accessing a writeprotected page triggers bluescreen,\nif you can read this it didn't work" << endl;
// BlueScreen 1
// asm("int $3");
// BlueScreen 2
log.info() << "Allocating page" << endl;
uint32_t* page = pg_alloc_page();
uint32_t* page = Kernel::pg_alloc_page();
*page = 42;
log.info() << "Writeprotecting page..." << endl;
pg_write_protect_page(page);
Kernel::pg_write_protect_page(page);
log.info() << "Accessing writeprotected page" << endl;
*page = 42; // We map logical to physical 1:1 so no need to do any lookup
@ -20,23 +20,23 @@ void PagingDemo::writeprotect_page() {
}
void PagingDemo::notpresent_page() {
kout << "Produces pagefault, if you can read this it didn't work" << endl;
Kernel::kout << "Produces pagefault, if you can read this it didn't work" << endl;
log.info() << "Allocating page" << endl;
uint32_t* page = pg_alloc_page();
uint32_t* page = Kernel::pg_alloc_page();
*page = 42;
log.info() << "Marking page notpresent..." << endl;
pg_notpresent_page(page);
Kernel::pg_notpresent_page(page);
log.info() << "Accessing page" << endl;
kout << "Page not accessible: " << *page << endl;
Kernel::kout << "Page not accessible: " << *page << endl;
// No free because bluescreen
}
void PagingDemo::run() {
kout << "Press w for writeprotect demo, n for notpresent demo" << endl;
Kernel::kout << "Press w for writeprotect demo, n for notpresent demo" << endl;
switch(listener.waitForKeyEvent()) {
case 'w':
writeprotect_page();
@ -46,5 +46,5 @@ void PagingDemo::run() {
break;
}
scheduler.exit();
Kernel::scheduler.exit();
}

View File

@ -5,23 +5,23 @@
#include "kernel/process/Thread.h"
#include "kernel/event/KeyEventListener.h"
class PagingDemo: public Thread {
class PagingDemo: public Kernel::Thread {
private:
void writeprotect_page();
void free_page();
void notpresent_page();
KeyEventListener listener;
Kernel::KeyEventListener listener;
public:
PagingDemo(const PagingDemo& copy) = delete;
PagingDemo(): Thread("PagingDemo"), listener(tid) {
kevman.subscribe(listener);
Kernel::kevman.subscribe(listener);
}
~PagingDemo() override {
kevman.unsubscribe(listener);
Kernel::kevman.unsubscribe(listener);
}
void run() override;

View File

@ -0,0 +1,34 @@
#include "PreemptiveThreadDemo.h"
void PreemptiveLoopThread::run() {
int cnt = 0;
while (running) {
// Basic synchronization by semaphore
Kernel::kout.lock();
// Saving + restoring Kernel::kout position doesn't help much as preemption still occurs
CGA_Stream::setpos(55, id);
Kernel::kout << fillw(3) << id << fillw(0) << ": " << dec << cnt++ << endl;
Kernel::kout.unlock();
}
Kernel::scheduler.exit();
}
void PreemptiveThreadDemo::run() {
Kernel::kout.lock();
Kernel::kout.clear();
Kernel::kout << "Preemptive Thread Demo:" << endl;
Kernel::kout << "Readying LoopThreads" << endl;
for (unsigned int i = 0; i < number_of_threads; ++i) {
Kernel::scheduler.ready<PreemptiveLoopThread>(i);
}
Kernel::kout << "Exiting main thread" << endl;
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -5,7 +5,7 @@
#include "kernel/process/Thread.h"
#include "lib/async/Semaphore.h"
class PreemptiveLoopThread : public Thread {
class PreemptiveLoopThread : public Kernel::Thread {
private:
int id;
@ -19,7 +19,7 @@ public:
void run() override;
};
class PreemptiveThreadDemo : public Thread {
class PreemptiveThreadDemo : public Kernel::Thread {
private:
unsigned int number_of_threads;

View File

@ -2,22 +2,22 @@
#include "kernel/process/IdleThread.h"
void SmartPointerDemo::run() {
kout.lock();
kout.clear();
Kernel::kout.lock();
Kernel::kout.clear();
kout << "Output is written to log to be able to trace memory allocations/deallocations" << endl;
Kernel::kout << "Output is written to log to be able to trace memory allocations/deallocations" << endl;
{
log.info() << "Allocating new unique_ptr<int>..." << endl;
bse::unique_ptr<int> ptr = bse::make_unique<int>(1);
Memory::unique_ptr<int> ptr = Memory::make_unique<int>(1);
log.info() << "Leaving scope..." << endl;
}
log.info() << "Should be deleted by now..." << endl;
{
log.info() << "Allocating new unique_ptr<int>..." << endl;
bse::unique_ptr<int> ptr1 = bse::make_unique<int>(1);
bse::unique_ptr<int> ptr2;
Memory::unique_ptr<int> ptr1 = Memory::make_unique<int>(1);
Memory::unique_ptr<int> ptr2;
log.info() << "*ptr1 == " << *ptr1 << ", (bool)ptr2 == " << static_cast<bool>(ptr2) << endl;
log.info() << "Moving ptr1 => ptr2 (no allocations should happen)..." << endl;
@ -30,8 +30,8 @@ void SmartPointerDemo::run() {
{
log.info() << "Allocating (2) new unique_ptr<int>..." << endl;
bse::unique_ptr<int> ptr1 = bse::make_unique<int>(1);
bse::unique_ptr<int> ptr2 = bse::make_unique<int>(1);
Memory::unique_ptr<int> ptr1 = Memory::make_unique<int>(1);
Memory::unique_ptr<int> ptr2 = Memory::make_unique<int>(1);
log.info() << "Moving ptr1 => ptr2 (ptr1 should be freed)..." << endl;
ptr2 = std::move(ptr1);
@ -44,7 +44,7 @@ void SmartPointerDemo::run() {
{
log.info() << "Allocating new unique_ptr<int[]>..." << endl;
bse::unique_ptr<int[]> ptr = bse::make_unique<int[]>(10);
Memory::unique_ptr<int[]> ptr = Memory::make_unique<int[]>(10);
ptr[0] = 1;
log.info() << "ptr[0] == " << ptr[0] << endl;
}
@ -52,8 +52,8 @@ void SmartPointerDemo::run() {
{
log.info() << "Allocating new unique_ptr<int[10]>..." << endl;
bse::unique_ptr<int[]> ptr1 = bse::make_unique<int[]>(10);
bse::unique_ptr<int[]> ptr2;
Memory::unique_ptr<int[]> ptr1 = Memory::make_unique<int[]>(10);
Memory::unique_ptr<int[]> ptr2;
log.info() << "Moving ptr1 => ptr2 (no allocations should happen)..." << endl;
ptr2 = std::move(ptr1);
@ -64,8 +64,8 @@ void SmartPointerDemo::run() {
{
log.info() << "Allocating (2) new unique_ptr<int[10]>..." << endl;
bse::unique_ptr<int> ptr1 = bse::make_unique<int>(10);
bse::unique_ptr<int> ptr2 = bse::make_unique<int>(10);
Memory::unique_ptr<int> ptr1 = Memory::make_unique<int>(10);
Memory::unique_ptr<int> ptr2 = Memory::make_unique<int>(10);
log.info() << "Moving ptr1 => ptr2 (ptr1 should be freed)..." << endl;
ptr2 = std::move(ptr1);
@ -76,7 +76,7 @@ void SmartPointerDemo::run() {
// NOTE: This wasn't working because of a missing operator[] delete in the allocator
log.info() << "Allocating unique_ptr<int>*..." << endl;
bse::unique_ptr<int>* ptrptr = new bse::unique_ptr<int>[10];
Memory::unique_ptr<int>* ptrptr = new Memory::unique_ptr<int>[10];
delete[] ptrptr;
log.info() << "Should be deleted by now..." << endl;
@ -84,9 +84,9 @@ void SmartPointerDemo::run() {
{
log.info() << "Stackallocating Array<bse::unique_ptr<int>, 10>..." << endl;
bse::array<bse::unique_ptr<int>, 10> arr;
Container::array<Memory::unique_ptr<int>, 10> arr;
log.info() << "Populating slot 0..." << endl;
arr[0] = bse::make_unique<int>(1);
arr[0] = Memory::make_unique<int>(1);
log.info() << "Moving slot 0 to slot 1..." << endl;
arr[1] = std::move(arr[0]);
log.info() << "Leaving scope" << endl;
@ -95,9 +95,9 @@ void SmartPointerDemo::run() {
{
log.info() << "Heapallocating Array<bse::unique_ptr<int>, 10>..." << endl;
bse::array<bse::unique_ptr<int>, 10>* arr = new bse::array<bse::unique_ptr<int>, 10>;
Container::array<Memory::unique_ptr<int>, 10>* arr = new Container::array<Memory::unique_ptr<int>, 10>;
log.info() << "Populating slot 0..." << endl;
(*arr)[0] = bse::make_unique<int>(1);
(*arr)[0] = Memory::make_unique<int>(1);
log.info() << "Moving slot 0 to slot 1..." << endl;
(*arr)[1] = std::move((*arr)[0]);
log.info() << "Deleting" << endl;
@ -108,15 +108,15 @@ void SmartPointerDemo::run() {
{
log.info() << "ArrayList<bse::unique_ptr<int>>..." << endl;
bse::vector<bse::unique_ptr<int>> vec;
Container::vector<Memory::unique_ptr<int>> vec;
log.info() << "2x insertion" << endl;
vec.push_back(bse::make_unique<int>(1));
vec.push_back(bse::make_unique<int>(2));
vec.push_back(Memory::make_unique<int>(1));
vec.push_back(Memory::make_unique<int>(2));
log.info() << "Leaving scope" << endl;
}
log.info() << "Should be deleted by now..." << endl;
kout.unlock();
scheduler.exit();
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -3,7 +3,7 @@
#include "kernel/system/Globals.h"
class SmartPointerDemo : public Thread {
class SmartPointerDemo : public Kernel::Thread {
public:
SmartPointerDemo(const SmartPointerDemo& copy) = delete;

View File

@ -0,0 +1,56 @@
#include "StringDemo.h"
void StringDemo::run() {
Kernel::kout.lock();
Kernel::kout.clear();
log.info() << "Allocating new string" << endl;
String::string str1 = "This is a dynamically allocated string!";
Kernel::kout << str1 << endl;
log.info() << "Reassign string" << endl;
str1 = "Hello";
Kernel::kout << str1 << " has length " << dec << str1.size() << endl;
Kernel::kout << "Again with strlen: Hello has length " << dec << String::strlen("Hello") << endl;
Kernel::kout << "Adding strings: " << str1 << " + World" << endl;
log.info() << "Adding strings" << endl;
str1 = str1 + " World";
Kernel::kout << str1 << endl;
Kernel::kout << "Hello += World" << endl;
log.info() << "Hello += World" << endl;
String::string str3 = "Hello";
str3 += " World";
Kernel::kout << str3 << endl;
Kernel::kout << "Hello World *= 3" << endl;
str3 *= 3;
Kernel::kout << str3 << endl;
Kernel::kout << "String iterator!" << endl;
for (const char c : str1) {
Kernel::kout << c << " ";
}
Kernel::kout << endl;
log.info() << "Allocating new string" << endl;
String::string str2 = "Hello World";
Kernel::kout << "str1 == str2: " << static_cast<int>(str1 == str2) << endl;
Kernel::kout << "strcmp(Hello, Hello): " << String::strcmp("Hello", "Hello") << endl;
log.info() << "Reassign str2" << endl;
str2 = "Hello";
Container::array<char, 5> arr{};
arr[0] = 'H';
arr[1] = 'e';
arr[2] = 'l';
arr[3] = 'l';
arr[4] = 'o';
Kernel::kout << "bse::array<char, 5> to bse::string: " << static_cast<String::string>(arr) << ", size: " << (String::string(arr)).size() << endl;
Kernel::kout << "(bse::string)arr (" << static_cast<String::string>(arr) << ") == str2 (" << str2 << "): " << static_cast<int>(String::string(arr) == str2) << endl;
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -3,7 +3,7 @@
#include "kernel/system/Globals.h"
class StringDemo : public Thread {
class StringDemo : public Kernel::Thread {
public:
StringDemo(const StringDemo& copy) = delete;

View File

@ -14,30 +14,30 @@ void TextDemo::run() {
/* Hier muess Code eingefuegt werden */
kout.lock();
kout.clear();
kout << "TextDemo\n"
Kernel::kout.lock();
Kernel::kout.clear();
Kernel::kout << "TextDemo\n"
<< endl;
kout << "Attribut (GREEN on WHITE): "
<< bgc(CGA::WHITE) << green << "GREEN on WHITE" << endl
Kernel::kout << "Attribut (GREEN on WHITE): "
<< bgc(Device::CGA::WHITE) << green << "GREEN on WHITE" << endl
<< "Attribut (WHITE on BLACK): "
<< bgc(CGA::BLACK) << white << "WHITE on BLACK" << endl;
kout << endl;
<< bgc(Device::CGA::BLACK) << white << "WHITE on BLACK" << endl;
Kernel::kout << endl;
kout << "Test der Zahlenausgabefunktion:" << endl
Kernel::kout << "Test der Zahlenausgabefunktion:" << endl
<< "| dec | hex | bin |" << endl
<< "+-------+-------+-------+" << endl;
for (uint16_t num = 0; num < 17; ++num) {
kout << fillw(0) << "| " << fillw(6) << dec << num
Kernel::kout << fillw(0) << "| " << fillw(6) << dec << num
<< fillw(0) << "| " << fillw(6) << hex << num
<< fillw(0) << "| " << fillw(6) << bin << num
<< fillw(0) << "|" << endl;
}
kout << endl;
Kernel::kout << endl;
kout.unlock();
scheduler.exit();
Kernel::kout.unlock();
Kernel::scheduler.exit();
}

View File

@ -14,7 +14,7 @@
#include "kernel/system/Globals.h"
#include "kernel/process/Thread.h"
class TextDemo : public Thread {
class TextDemo : public Kernel::Thread {
public:
TextDemo(const TextDemo& copy) = delete;

View File

@ -26,9 +26,9 @@ int VBEdemo::linInterPol1D(int x, int xr, int l, int r) {
* Beschreibung: Farbwert in zwei Dimensionen interpoliert berechnen. *
*****************************************************************************/
int VBEdemo::linInterPol2D(int x, int y, int lt, int rt, int lb, int rb) {
return linInterPol1D(y, vesa.yres,
linInterPol1D(x, vesa.xres, lt, rt),
linInterPol1D(x, vesa.xres, lb, rb));
return linInterPol1D(y, Kernel::vesa.yres,
linInterPol1D(x, Kernel::vesa.xres, lt, rt),
linInterPol1D(x, Kernel::vesa.xres, lb, rb));
}
/*****************************************************************************
@ -42,7 +42,7 @@ void VBEdemo::drawColors() {
for (int y = 0; y < y_res; y++) {
for (int x = 0; x < x_res; x++) {
vesa.drawPixel(x, y, linInterPol2D(x, y, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFF00));
Kernel::vesa.drawPixel(x, y, linInterPol2D(x, y, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFF00));
}
}
}
@ -60,7 +60,7 @@ void VBEdemo::drawBitmap() {
/* Hier muss Code eingefuegt werden */
vesa.drawSprite(sprite_width, sprite_height, sprite_bpp, sprite_pixel);
Kernel::vesa.drawSprite(sprite_width, sprite_height, sprite_bpp, sprite_pixel);
}
/*****************************************************************************
@ -72,12 +72,8 @@ void VBEdemo::drawFonts() {
/* Hier muss Code eingefuegt werden */
vesa.drawString(std_font_8x8, 0, 300, 0, "STD FONT 8x8", 12);
vesa.drawString(std_font_8x16, 0, 320, 0, "STD FONT 8x16", 13);
vesa.drawString(acorn_font_8x8, 0, 340, 0, "ACORN FONT 8x8", 14);
vesa.drawString(sun_font_8x16, 0, 360, 0, "SUN FONT 8x16", 13);
vesa.drawString(sun_font_12x22, 0, 380, 0, "SUN FONT 12x22", 14);
vesa.drawString(pearl_font_8x8, 0, 400, 0, "PEARL FONT 8x8", 14);
Kernel::vesa.drawString(Graphics::std_font_8x8, 0, 300, 0, "STD FONT 8x8", 12);
Kernel::vesa.drawString(Graphics::std_font_8x16, 0, 320, 0, "STD FONT 8x16", 13);
}
/*****************************************************************************
@ -89,18 +85,18 @@ void VBEdemo::drawFonts() {
void VBEdemo::run() {
// In den Grafikmodus schalten (32-Bit Farbtiefe)
vesa.initGraphicMode(MODE_640_480_24BITS);
vesa.setDrawingBuff(BUFFER_VISIBLE);
Kernel::vesa.initGraphicMode(Device::MODE_640_480_24BITS);
Kernel::vesa.setDrawingBuff(Device::BUFFER_VISIBLE);
drawColors();
/* Hier muss Code eingefuegt werden */
vesa.drawRectangle(100, 100, 300, 300, 0);
Kernel::vesa.drawRectangle(100, 100, 300, 300, 0);
drawBitmap();
drawFonts();
while (running) {}
// selbst terminieren
scheduler.exit();
Kernel::scheduler.exit();
}

Some files were not shown because too many files have changed in this diff Show More