Reworks BSOD into fancy BSOD.
This commit is contained in:
parent
245895d7bd
commit
e97921e246
4 changed files with 86 additions and 54 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in a new issue