diff --git a/src/menu/rom_database.c b/src/menu/rom_database.c index 2bedb25f..2d16b4cf 100644 --- a/src/menu/rom_database.c +++ b/src/menu/rom_database.c @@ -76,9 +76,9 @@ rom_header_t file_read_rom_header(char *path) { fseek(fp, 0x3E, SEEK_SET); fread(&(rom_header->metadata.destination_market), sizeof(rom_header->metadata.destination_market), 1, fp); fseek(fp, 0x3F, SEEK_SET); - fread(&(rom_header->version), sizeof(rom_header->version), 1, fp); + fread(&(rom_header->metadata.version), sizeof(rom_header->metadata.version), 1, fp); fseek(fp, 0x40, SEEK_SET); - fread(&(rom_header->ipl3_boot_code), sizeof(rom_header->ipl3_boot_code), 1, fp); + fread(&(rom_header->ipl_boot_code), sizeof(rom_header->ipl_boot_code), 1, fp); fclose(fp); @@ -96,12 +96,12 @@ uint8_t rom_db_match_save_type(rom_header_t rom_header) { // First: Match by the `ED` or `HB` Developer ID if (rom_header.metadata.unique_identifier == *(uint16_t *)"ED" || rom_header.metadata.unique_identifier == *(uint16_t *)"HB") { // #ifdef ED64_COMPATIBLE -// uint8_t low_nibble = rom_header.version & 0x0F; +// uint8_t low_nibble = rom_header.metadata.version & 0x0F; // uint8_t rtc_enabled = extract_homebrew_setting(low_nibble, 0); // Bit 0 // uint8_t region_free_enabled = extract_homebrew_setting(low_nibble, 1); // Bit 1 // #endif - uint8_t high_nibble = (rom_header.version >> 4) & 0x0F; + uint8_t high_nibble = (rom_header.metadata.version >> 4) & 0x0F; return extract_homebrew_save_type(high_nibble); } diff --git a/src/menu/rom_database.h b/src/menu/rom_database.h index 5fff49c5..ac62cb78 100644 --- a/src/menu/rom_database.h +++ b/src/menu/rom_database.h @@ -124,7 +124,7 @@ typedef enum { MARKET_CHINA = 'C', /** @brief The ROM is designed for Germany (probably PAL). */ MARKET_GERMANY = 'D', - /** @brief The ROM is designed for USA. */ + /** @brief The ROM is designed for USA. (probably NTSC-M) */ MARKET_USA = 'E', /** @brief The ROM is designed for France (probably PAL). */ MARKET_FRANCE = 'F', @@ -134,7 +134,7 @@ typedef enum { MARKET_NETHERLANDS = 'H', /** @brief The ROM is designed for Italy (probably PAL). */ MARKET_ITALY = 'I', - /** @brief The ROM is designed for Japan. */ + /** @brief The ROM is designed for Japan. (probably NTSC-J) */ MARKET_JAPAN = 'J', /** @brief The ROM is designed for Korea. */ MARKET_KOREA = 'K', @@ -165,6 +165,27 @@ typedef enum { } rom_destination_market_t; +/** + * @brief ROM Config Flags Structure + * @note This information is derived from the ROM header. + * @see https://n64brew.dev/wiki/Peripheral_Interface#Domains + * i.e. + * 0x00 = PI BSD Domain 1 Release register + * 0x01 = PI BSD Domain 1 Page Size register + * 0x02 = PI BSD Domain 1 Pulse Width register + * 0x03 = PI BSD Domain 1 Latch register + */ +typedef struct { + /* PI BSD Domain 1 Release register value */ + uint8_t domain1_release; + /* PI BSD Domain 1 Page Size register value */ + uint8_t domain1_page_size; + /* PI BSD Domain 1 Pulse Width register value */ + uint8_t domain1_latency; + /* PI BSD Domain 1 Latch register value */ + uint8_t domain1_pulse_width; +} rom_config_flags_t; + /** * @brief ROM Metadata Structure * @note This information is derived from the ROM header. i.e. @@ -173,9 +194,10 @@ typedef enum { * 0x3E = Destination Market */ typedef struct { - rom_media_type_t media_type; + uint8_t media_type; // rom_media_type_t uint16_t unique_identifier; uint8_t destination_market; // rom_destination_market_t + uint8_t version; } rom_metadata_t; /** @@ -184,7 +206,7 @@ typedef struct { */ typedef struct { /** @brief The ROM configuration flags @note we currently use this to work out the endian @see rom_endian_type_t. */ - uint32_t config_flags; + uint32_t config_flags; // TODO: use rom_config_flags_t /** @brief The ROM file clock rate. */ uint32_t clock_rate; @@ -196,21 +218,20 @@ typedef struct { /** @brief The ROM file checksum. */ uint64_t checksum; - /** @brief The ROM file unknown reserved region at 0x18. */ + /** @brief The ROM file unknown reserved region at 0x18. for 8 bytes */ uint64_t unknown_reserved_1; /** @brief The ROM file title */ - char title[21]; // 20 chars + null + char title[21]; // 20 chars + null char - /** @brief The ROM file unknown reserved region at 0x34. */ + /** @brief The ROM file unknown reserved region at 0x34. for 7 bytes */ char unknown_reserved_2[7]; /** @brief The ROM file metadata @see rom_metadata_t. */ rom_metadata_t metadata; /** @brief The ROM file release version. */ - uint8_t version; - char ipl3_boot_code[0xFC0]; + char ipl_boot_code[0x0FC0]; } rom_header_t; diff --git a/src/menu/views/load.c b/src/menu/views/load.c index 56d9158b..1a9bfc2f 100644 --- a/src/menu/views/load.c +++ b/src/menu/views/load.c @@ -124,6 +124,16 @@ static char *format_rom_expansion_pak_info (rom_memorytype_t expansion_pak_info) } } +static float format_rom_clockrate (uint32_t clockrate) { + /* Generally ROMs have a clock rate of 0x0000000F which signifies they used the default 62.5MHz clock. */ + if (clockrate == 0x0F) { + return 62.5; + } + + /* If it did not, we need to show the different value. */ + return (float) clockrate / 1000000; +} + static void process (menu_t *menu) { if (menu->actions.enter) { @@ -167,20 +177,22 @@ static void draw (menu_t *menu, surface_t *d) { " Save type: %s\n" " Expansion PAK: %s\n" "\n" - " Extra info:\n" + " Extra information:\n" " Boot address: 0x%08lX\n" - " SDK version: %.1f%c", + " SDK version: %.1f%c\n" + " Clock Rate: %.2fMHz\n", format_rom_endian(rom_header.config_flags), rom_header.title, rom_header.metadata.media_type, format_rom_media_type(rom_header.metadata.media_type), (char *) (&rom_header.metadata.unique_identifier), rom_header.metadata.destination_market, format_rom_destination_market(rom_header.metadata.destination_market), - rom_header.version, + rom_header.metadata.version, rom_header.checksum, format_rom_save_type(rom_db_match_save_type(rom_header)), format_rom_expansion_pak_info(rom_db_match_expansion_pak(rom_header)), rom_header.boot_address, - (float) ((rom_header.sdk_version >> 8) & 0xFF) / 10.0f, (char) (rom_header.sdk_version & 0xFF) + (float) ((rom_header.sdk_version >> 8) & 0xFF) / 10.0f, (char) (rom_header.sdk_version & 0xFF), + format_rom_clockrate(rom_header.clock_rate) ); component_actions_bar_text_draw(