From ab3b94da975adb49fa7737f57075d242b1addd9d Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 31 Mar 2024 23:49:32 -0500 Subject: [PATCH] Detect type of BIOS --- .../src/Overlay/BIOSInfo/bios_info.cpp | 47 ++++++++-- include/PSX/System/syscalls.hpp | 42 ++++++--- include/string.h | 1 + src/Library/src/BootLoader/start_boot.cpp | 12 +++ src/Library/src/System/string.cpp | 17 ++++ src/Library/src/System/syscall.cpp | 91 ++++++++++++++----- 6 files changed, 165 insertions(+), 45 deletions(-) diff --git a/examples/PoolBox/application/src/Overlay/BIOSInfo/bios_info.cpp b/examples/PoolBox/application/src/Overlay/BIOSInfo/bios_info.cpp index d7d371d7..7c94562e 100644 --- a/examples/PoolBox/application/src/Overlay/BIOSInfo/bios_info.cpp +++ b/examples/PoolBox/application/src/Overlay/BIOSInfo/bios_info.cpp @@ -48,16 +48,16 @@ namespace BIOSInfo { }; static struct { - using BIOSStringOffset = const char*const (SysCall::BIOSVersion::*); + using BIOSStringOffset = const char*const (BIOS::Version::*); const BIOSStringOffset bios_str_offset; const char*const display_str; FontSlider font_slider; } BIOSStringInfo[] = { - {.bios_str_offset = &SysCall::BIOSVersion::kernel_maker, .display_str = "Kernel-Maker"}, - {.bios_str_offset = &SysCall::BIOSVersion::version_str, .display_str = "Version"}, - {.bios_str_offset = &SysCall::BIOSVersion::gui_version, .display_str = "GUI-Version"}, - {.bios_str_offset = &SysCall::BIOSVersion::copyright, .display_str = "Copyright"}, + {.bios_str_offset = &BIOS::Version::kernel_maker, .display_str = "Kernel-Maker"}, + {.bios_str_offset = &BIOS::Version::version_str, .display_str = "Version"}, + {.bios_str_offset = &BIOS::Version::gui_version, .display_str = "GUI-Version"}, + {.bios_str_offset = &BIOS::Version::copyright, .display_str = "Copyright"}, }; static GPU::TILE::Linked border_tiles[2] = { @@ -65,18 +65,47 @@ namespace BIOSInfo { Make::TILE(Make::AreaI16(GPU::Display::Width - TextOffset.x, 0, TextOffset.x, GPU::Display::Height - 32), GPU::Color24::Black()).linked() }; - static SysCall::BIOSVersion setup() { - const auto result = SysCall::get_bios_version(); + static const char* bios_name = nullptr; + static FontSlider bios_name_slider; + + static const char* get_bios_name() { + switch(BIOS::type) { + case BIOS::Type::Devboard: + return "DevBoard"; + case BIOS::Type::PS1: + return "PS1"; + case BIOS::Type::PS2: + return "PS2"; + case BIOS::Type::PS3: + return "PS3"; + case BIOS::Type::PSCompatible: + return "Unkown PS compatible BIOS"; + case BIOS::Type::No$psx: + return "NO$PSX"; + case BIOS::Type::XEBRA: + return "XEBRA"; + default: + return "Unkown"; + } + } + + static BIOS::Version setup() { + const auto result = BIOS::get_bios_version(); + + if(!bios_name) { + bios_name = get_bios_name(); + } Shared::back_menu.reset(); for(auto& bios_str_info : BIOSStringInfo) { bios_str_info.font_slider = FontSlider::create_for(FontWriter::BIOSFont::Info, result.*(bios_str_info.bios_str_offset)); } + bios_name_slider = FontSlider::create_for(FontWriter::BIOSFont::Info, bios_name); border_tiles[0].concat(border_tiles[1]); return result; } - static bool update_or_exit(const SysCall::BIOSVersion& bios_version) { + static bool update_or_exit(const BIOS::Version& bios_version) { static const auto move_cursor = [](JabyEngine::Cursor& cursor, int16_t dx, int16_t old_x) -> JabyEngine::Cursor& { cursor.pos.x = (old_x - dx); return cursor; @@ -97,6 +126,8 @@ namespace BIOSInfo { FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "%s:\n", bios_str_info.display_str); FontWriter::bios_font_writer.write(move_cursor(cursor, bios_str_info.font_slider.count, old_pos_x), "%s\n", bios_version.*(bios_str_info.bios_str_offset)); } + FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "BIOS Type:\n"); + FontWriter::bios_font_writer.write(move_cursor(cursor, bios_name_slider.count, old_pos_x), "%s\n", bios_name); FontWriter::bios_font_writer.write(move_cursor(cursor, 0, old_pos_x), "----------------\n"); return false; diff --git a/include/PSX/System/syscalls.hpp b/include/PSX/System/syscalls.hpp index cd1aa7b2..ca181155 100644 --- a/include/PSX/System/syscalls.hpp +++ b/include/PSX/System/syscalls.hpp @@ -17,6 +17,34 @@ R31 ra Return address (set by function call) */ namespace JabyEngine { + namespace BIOS { + struct Version { + struct { + uint8_t day; + uint8_t month; + uint16_t year; + } date; + const char* kernel_maker; + const char* version_str; + const char* gui_version; + const char* copyright; + }; + + enum struct Type { + Devboard, + PS1, + PS2, + PS3, + PSCompatible, // internal usage only + No$psx, + XEBRA, + Unkown + }; + + Version get_bios_version(); + extern Type type; + } + namespace SysCall { static constexpr const uint32_t Table_A = 0xA0; static constexpr const uint32_t Table_B = 0xB0; @@ -55,20 +83,6 @@ namespace JabyEngine { }; #pragma pack(pop) - struct BIOSVersion { - struct { - uint8_t day; - uint8_t month; - uint16_t year; - } date; - const char* kernel_maker; - const char* version_str; - const char* gui_version; - const char* copyright; - }; - - BIOSVersion get_bios_version(); - #define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table) static __always_inline void* memcpy(void *dst, const void *src, size_t len) { diff --git a/include/string.h b/include/string.h index 0d1fa71d..a532c14c 100644 --- a/include/string.h +++ b/include/string.h @@ -3,6 +3,7 @@ #include "PSX/jabyengine_defines.h" START_C_FUNCTIONS + int strncmp(const char* s1, const char* s2, size_t n); size_t strlen(const char* str); END_C_FUNCTIONS diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 18ea2aa4..dcf0cb3b 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -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(); diff --git a/src/Library/src/System/string.cpp b/src/Library/src/System/string.cpp index 89f4a35f..58076a4a 100644 --- a/src/Library/src/System/string.cpp +++ b/src/Library/src/System/string.cpp @@ -1,6 +1,23 @@ #include 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; diff --git a/src/Library/src/System/syscall.cpp b/src/Library/src/System/syscall.cpp index 33940983..a98f0b04 100644 --- a/src/Library/src/System/syscall.cpp +++ b/src/Library/src/System/syscall.cpp @@ -3,41 +3,86 @@ #include 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(0xBFC00100); + } - No$PSX: - Date: 21.07.2016 - Version: no$psx + static const char* get_kernel_maker_str() { + return reinterpret_cast(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 = [](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(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(date_bcd & 0xFF)); version.date.month = from_bcd(static_cast((date_bcd >> 8) & 0xFF)); version.date.year = from_bcd(static_cast(date_bcd >> 16)); - version.kernel_maker = reinterpret_cast(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(0xBFC7FF32); version.copyright = version.gui_version + (strlen(version.gui_version) + 1); return version; } + + Type type = Type::Unkown; } } \ No newline at end of file