Reworks BSOD into fancy BSOD.

This commit is contained in:
Felix Queißner 2016-05-06 23:50:45 +02:00
parent 245895d7bd
commit e97921e246
4 changed files with 86 additions and 54 deletions

View file

@ -22,7 +22,17 @@ struct NumericFormat
{
T value;
uint32_t base;
/**
* Applies a padding to the number.
* A positive number will apply padding the right side,
* a negative number will pad the left side.
*/
int32_t padding = 0;
char padchar = ' ';
NumericFormat(T value) : value(value), base(10) { }
NumericFormat(T value, uint32_t base) : value(value), base(base) { }
};
@ -42,6 +52,17 @@ namespace console_tools
template<typename T>
auto nbase(T value, uint32_t base) { return NumericFormat<T>(value, base); }
template<typename T>
auto pad(NumericFormat<T> value, int32_t padding, char c = ' ') {
value.padding = padding;
return value;
}
template<typename T>
auto pad(T value, int32_t padding, char c = ' ') {
return pad(NumericFormat<T>(value), padding, c);
}
}
class Console
@ -62,8 +83,14 @@ private:
/**
* Prints the prefix for a given numeric base.
* @returns the prefix length.
*/
void printNumericPrefix(uint32_t base);
uint32_t printNumericPrefix(uint32_t base);
/**
* Prints a character several times.
*/
void putrep(char c, uint32_t repetitions);
public:
Console(Screen *screen);

View file

@ -100,7 +100,7 @@ extern "C" void init(Structure const & data)
asm volatile("sti");
// asm volatile ("int $0x00");
asm volatile ("int $0x00");
// Console::main << "Interrupts enabled.\n";

View file

@ -33,36 +33,42 @@ void BSOD::die(Error code, const char *msg)
void BSOD::die(Error code, const char *msg, CpuState *cpu)
{
using namespace console_tools;
FColor Y(Color::Yellow);
FColor W(Color::White);
asm volatile ("cli");
Console::main << FColor(Color::White) << BColor(Color::Red);
Console::main.clear();
Console::main
<< "OH MY GOD. DasOS crashed! But i can tell you: \n";
<< " ___ __ __ ___ " << "\n"
<< " / _ \\| \\/ |/ __|" << "\n"
<< " | (_) | |\\/| | (_ |" << "\n"
<< " \\___/|_| |_|\\___|" << "\n"
<< "\n";
Console::main
<< "DasOS crashed!\n"
<< "\n"
<< "CODE: " << Y;
switch(code) {
#define ERROR(num, ident, desc) case Error::ident: Console::main << #desc << "\n"; break;
#define ERROR(num, ident, desc) case Error::ident: Console::main << #ident << " / " << #desc << "\n"; break;
#include "errors.lst"
#undef ERROR
}
Console::main
<< msg << "\n"
<< "Also here is some CPU information:\n";
<< W << "MSG: " << Y
<< msg << W << "\n"
<< "\n"
<< "CPU State:\n";
Console::main
<< "eax = " << hex(cpu->eax) << "\n"
<< "ebx = " << hex(cpu->ebx) << "\n"
<< "ecx = " << hex(cpu->ecx) << "\n"
<< "edx = " << hex(cpu->edx) << "\n"
<< "esi = " << hex(cpu->esi) << "\n"
<< "edi = " << hex(cpu->edi) << "\n"
<< "ebp = " << hex(cpu->ebp) << "\n"
<< "intr = " << cpu->interrupt << "(" << toString(cpu->interrupt) << ")" << "\n"
<< "error = " << cpu->error << "\n"
<< "eip = " << hex(cpu->eip) << "\n"
<< "cs = " << hex(cpu->cs) << "\n"
<< "eflags = " << bin(cpu->eflags) << "\n"
<< "esp = " << hex(cpu->esp) << "\n"
<< "ss = " << hex(cpu->ss) << "\n";
<< W << "eax = " << Y << pad(hex(cpu->eax), 10) << W << " esi = " << Y << pad(hex(cpu->esi), 10) << W << " edx = " << Y << pad(hex(cpu->edx), 10) << W << " esp = " << Y << pad(hex(cpu->esp), 10) << "\n"
<< W << "ebx = " << Y << pad(hex(cpu->ebx), 10) << W << " edi = " << Y << pad(hex(cpu->edi), 10) << W << " eip = " << Y << pad(hex(cpu->eip), 10) << W << " flg = " << Y << bin(cpu->eflags) << "\n"
<< W << "ecx = " << Y << pad(hex(cpu->ecx), 10) << W << " ebp = " << Y << pad(hex(cpu->ebp), 10) << W << " cs = " << Y << pad(hex(cpu->cs), 10) << W << " ss = " << Y << pad(hex(cpu->ss), 10) << "\n"
<< W << "int = " << Y << pad(cpu->interrupt, 10) << W << " err = " << Y << pad(cpu->error, 10) << W << " " << toString(cpu->interrupt);
asm volatile ("hlt");
while(true);

View file

@ -164,63 +164,62 @@ Console & Console::operator << <virtual_t_ident>(virtual_t ptr)
return *this;
}
#define NUMERIC_FMT_HANDLER char buffer[13]; \
size_t prefixlen = this->printNumericPrefix(fmt.base); \
size_t len = Numeric::toString(buffer, sizeof(buffer), fmt.value, fmt.base); \
int delta = prefixlen + len; \
if(fmt.padding < 0 && delta < -fmt.padding) { \
this->putrep(fmt.padchar, -fmt.padding - delta); \
} \
for(size_t i = 0; i < len; i++) { \
this->put(buffer[i]); \
} \
if(fmt.padding > 0 && delta < fmt.padding) { \
this->putrep(fmt.padchar, fmt.padding - delta); \
} \
return *this
template<>
Console & Console::operator << <uint32_t>(const NumericFormat<uint32_t> & fmt)
{
char buffer[13];
this->printNumericPrefix(fmt.base);
size_t len = Numeric::toString(buffer, sizeof(buffer), fmt.value, fmt.base);
for(size_t i = 0; i < len; i++) {
this->put(buffer[i]);
}
return *this;
NUMERIC_FMT_HANDLER;
}
template<>
Console & Console::operator << <int32_t>(const NumericFormat<int32_t> & fmt)
{
char buffer[13];
this->printNumericPrefix(fmt.base);
size_t len = Numeric::toString(buffer, sizeof(buffer), fmt.value, fmt.base);
for(size_t i = 0; i < len; i++) {
this->put(buffer[i]);
}
return *this;
NUMERIC_FMT_HANDLER;
}
template<>
Console & Console::operator << <uint64_t>(const NumericFormat<uint64_t> & fmt)
{
char buffer[13];
this->printNumericPrefix(fmt.base);
size_t len = Numeric::toString(buffer, sizeof(buffer), fmt.value, fmt.base);
for(size_t i = 0; i < len; i++) {
this->put(buffer[i]);
}
return *this;
NUMERIC_FMT_HANDLER;
}
template<>
Console & Console::operator << <int64_t>(const NumericFormat<int64_t> & fmt)
{
char buffer[13];
this->printNumericPrefix(fmt.base);
size_t len = Numeric::toString(buffer, sizeof(buffer), fmt.value, fmt.base);
for(size_t i = 0; i < len; i++) {
this->put(buffer[i]);
}
return *this;
NUMERIC_FMT_HANDLER;
}
void Console::printNumericPrefix(uint32_t base)
uint32_t Console::printNumericPrefix(uint32_t base)
{
switch(base) {
case 2: *this << "0b"; break;
case 8: *this << "0o"; break;
case 10: return;
case 16: *this << "0x"; break;
case 2: *this << "0b"; return 2;
case 8: *this << "0o"; return 2;
case 10: return 0;
case 16: *this << "0x"; return 2;
default:
*this << "[" << base << "]x";
break;
if(base < 10) return 4;
if(base < 100) return 5;
return 6;
}
}
void Console::putrep(char c, uint32_t repetitions)
{
for(uint32_t i = 0; i < repetitions; i++)
this->put(c);
}