Detect type of BIOS
This commit is contained in:
@@ -100,13 +100,25 @@ namespace JabyEngine {
|
||||
}
|
||||
}
|
||||
|
||||
namespace BIOS {
|
||||
namespace internal {
|
||||
Type get_bios_type();
|
||||
}
|
||||
}
|
||||
|
||||
namespace boot {
|
||||
namespace Start {
|
||||
static void identify_bios() {
|
||||
BIOS::type = BIOS::internal::get_bios_type();
|
||||
}
|
||||
|
||||
static void setup() {
|
||||
static constexpr auto DebugX = 1;
|
||||
static constexpr auto DebugY = 0;
|
||||
static constexpr auto DebugScale = 1.0;
|
||||
|
||||
identify_bios();
|
||||
|
||||
__debug_boot_color_at(::JabyEngine::GPU::Color24::Grey(), DebugX, DebugY, DebugScale);
|
||||
DMA::setup();
|
||||
|
||||
|
@@ -1,6 +1,23 @@
|
||||
#include <string.h>
|
||||
|
||||
START_C_FUNCTIONS
|
||||
int strncmp(const char* s1, const char* s2, size_t n) {
|
||||
if(n == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
if(*s1 != *s2++) {
|
||||
return (*(unsigned char *)s1 - *(unsigned char *)--s2);
|
||||
}
|
||||
|
||||
if(*s1++ == 0) {
|
||||
break;
|
||||
}
|
||||
} while(--n != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t strlen(const char *str) {
|
||||
const char* end = str;
|
||||
|
||||
|
@@ -3,41 +3,86 @@
|
||||
#include <string.h>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace SysCall {
|
||||
BIOSVersion get_bios_version() {
|
||||
/*
|
||||
XEBRA:
|
||||
Date: 03.12.2016
|
||||
Version: XEBRA
|
||||
namespace BIOS {
|
||||
static uint32_t get_bcd_version() {
|
||||
return *reinterpret_cast<uint32_t*>(0xBFC00100);
|
||||
}
|
||||
|
||||
No$PSX:
|
||||
Date: 21.07.2016
|
||||
Version: no$psx
|
||||
static const char* get_kernel_maker_str() {
|
||||
return reinterpret_cast<const char*>(0xBFC00108);
|
||||
}
|
||||
|
||||
PS3:
|
||||
Date: 12.10.2011 (17.01.2000 for PS2?)
|
||||
Version: System ROM Version 5.0
|
||||
*/
|
||||
static const auto get_version_str = [](const char* kernel_maker) -> const char* {
|
||||
const char* start = kernel_maker + (strlen(kernel_maker) + 1);
|
||||
static const char* get_version_str() {
|
||||
const char* kernel_maker = get_kernel_maker_str();
|
||||
const char* ver_start = kernel_maker + (strlen(kernel_maker) + 1);
|
||||
|
||||
while(*start == 0) {
|
||||
start++;
|
||||
}
|
||||
return start;
|
||||
while(*ver_start == 0) {
|
||||
ver_start++;
|
||||
}
|
||||
return ver_start;
|
||||
}
|
||||
|
||||
// TODO: Move these to boot up code!!
|
||||
static Type get_raw_bios_type() {
|
||||
static const auto str_length = []<size_t N>(const char (&name)[N]) -> size_t {
|
||||
return N - 1;
|
||||
};
|
||||
BIOSVersion version;
|
||||
const char dev_str[] = "DTL-";
|
||||
const char ps1_str[] = "CEX-";
|
||||
const char ps_compatible_str[] = "PS compatible mode";
|
||||
const char no$psx_str[] = "no$psx";
|
||||
const char xebra_str[] = "XEBRA";
|
||||
|
||||
const auto date_bcd = *reinterpret_cast<uint32_t*>(0xBFC00100);
|
||||
const struct {
|
||||
const char* name;
|
||||
size_t name_length;
|
||||
Type type;
|
||||
} bioses[] = {
|
||||
// Sorted by likeliness
|
||||
{.name = ps1_str, .name_length = str_length(ps1_str), .type = Type::PS1},
|
||||
{.name = ps_compatible_str, .name_length = str_length(ps_compatible_str), .type = Type::PSCompatible},
|
||||
{.name = no$psx_str, .name_length = str_length(no$psx_str), .type = Type::No$psx},
|
||||
{.name = xebra_str, .name_length = str_length(xebra_str), .type = Type::XEBRA},
|
||||
{.name = dev_str, .name_length = str_length(dev_str), .type = Type::Devboard}
|
||||
};
|
||||
|
||||
const char*const version_str = get_version_str();
|
||||
for(const auto& bios : bioses) {
|
||||
if(strncmp(version_str, bios.name, bios.name_length) == 0) {
|
||||
return bios.type;
|
||||
}
|
||||
}
|
||||
return Type::Unkown;
|
||||
}
|
||||
|
||||
static Type refine_bios_type(Type type) {
|
||||
if(type == Type::PSCompatible) {
|
||||
const auto bios_year_bcd = get_bcd_version() >> 16;
|
||||
return bios_year_bcd == 0x2011 ? Type::PS3 : Type::PS2;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
Type get_bios_type() {
|
||||
return refine_bios_type(get_raw_bios_type());
|
||||
}
|
||||
}
|
||||
|
||||
Version get_bios_version() {
|
||||
Version version;
|
||||
const auto date_bcd = get_bcd_version();
|
||||
|
||||
version.date.day = from_bcd(static_cast<uint8_t>(date_bcd & 0xFF));
|
||||
version.date.month = from_bcd(static_cast<uint8_t>((date_bcd >> 8) & 0xFF));
|
||||
version.date.year = from_bcd(static_cast<uint16_t>(date_bcd >> 16));
|
||||
version.kernel_maker = reinterpret_cast<const char*>(0xBFC00108);
|
||||
version.version_str = get_version_str(version.kernel_maker);
|
||||
version.kernel_maker = get_kernel_maker_str();
|
||||
version.version_str = get_version_str();
|
||||
version.gui_version = reinterpret_cast<const char*>(0xBFC7FF32);
|
||||
version.copyright = version.gui_version + (strlen(version.gui_version) + 1);
|
||||
return version;
|
||||
}
|
||||
|
||||
Type type = Type::Unkown;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user