diff --git a/core/hw/flashrom/flashrom.h b/core/hw/flashrom/flashrom.h index e4e6dd356..0955ae05b 100644 --- a/core/hw/flashrom/flashrom.h +++ b/core/hw/flashrom/flashrom.h @@ -650,7 +650,11 @@ private: phys_id++; } - verify(phys_id < phys_end); + if (phys_id >= phys_end) + { + WARN_LOG(FLASHROM, "Cannot allocate block in flash. Full?"); + return 0; + } // mark the block as allocated set_allocated(bitmap, phys_id); diff --git a/core/hw/holly/sb_mem.cpp b/core/hw/holly/sb_mem.cpp index d595f323c..d80e3a57f 100644 --- a/core/hw/holly/sb_mem.cpp +++ b/core/hw/holly/sb_mem.cpp @@ -103,20 +103,12 @@ static void add_isp_to_nvmem(DCFlashChip *flash) } } -static bool nvmem_load(const string& root) +void FixUpFlash() { - bool rc; - if (settings.platform.system == DC_PLATFORM_DREAMCAST) - rc = sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram"); - else - rc = sys_nvmem->Load(get_game_save_prefix() + ".nvmem"); - if (!rc) - INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file..."); - if (settings.platform.system == DC_PLATFORM_DREAMCAST) { static_cast(sys_nvmem)->Validate(); - + // overwrite factory flash settings if (settings.dreamcast.region <= 2) { @@ -133,11 +125,11 @@ static bool nvmem_load(const string& root) sys_nvmem->data[0x1a004] = '0' + settings.dreamcast.broadcast; sys_nvmem->data[0x1a0a4] = '0' + settings.dreamcast.broadcast; } - + // overwrite user settings struct flash_syscfg_block syscfg; int res = static_cast(sys_nvmem)->ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg); - + if (!res) { // write out default settings @@ -153,12 +145,23 @@ static bool nvmem_load(const string& root) syscfg.time_hi = time >> 16; if (settings.dreamcast.language <= 5) syscfg.lang = settings.dreamcast.language; - + if (static_cast(sys_nvmem)->WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1) WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM"); add_isp_to_nvmem(static_cast(sys_nvmem)); } +} + +static bool nvmem_load(const string& root) +{ + bool rc; + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + rc = sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram"); + else + rc = sys_nvmem->Load(get_game_save_prefix() + ".nvmem"); + if (!rc) + INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file..."); if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) sys_rom->Load(get_game_save_prefix() + ".nvmem2"); @@ -207,15 +210,15 @@ bool LoadHle(const string& root) return reios_init(sys_rom->data, sys_nvmem); } -u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem->Read(addr,sz); } -void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem->Write(addr,data,sz); } +static u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem->Read(addr,sz); } +static void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem->Write(addr,data,sz); } -u32 ReadBios(u32 addr,u32 sz) +static u32 ReadBios(u32 addr,u32 sz) { return sys_rom->Read(addr, sz); } -void WriteBios(u32 addr,u32 data,u32 sz) +static void WriteBios(u32 addr,u32 data,u32 sz) { if (settings.platform.system == DC_PLATFORM_ATOMISWAVE) { @@ -484,7 +487,7 @@ void sh4_area0_Term() //AREA 0 -_vmem_handler area0_handler; +static _vmem_handler area0_handler; void map_area0_init() diff --git a/core/hw/sh4/sh4_mem.h b/core/hw/sh4/sh4_mem.h index 153d3a527..eeb06f43d 100644 --- a/core/hw/sh4/sh4_mem.h +++ b/core/hw/sh4/sh4_mem.h @@ -101,3 +101,4 @@ u32 GetRamPageFromAddress(u32 RamAddress); bool LoadRomFiles(const string& root); void SaveRomFiles(const string& root); bool LoadHle(const string& root); +void FixUpFlash(); diff --git a/core/nullDC.cpp b/core/nullDC.cpp index 0a9e0d373..0654568cd 100755 --- a/core/nullDC.cpp +++ b/core/nullDC.cpp @@ -38,6 +38,8 @@ static bool safemode_game; static bool tr_poly_depth_mask_game; static bool extra_depth_game; static bool disable_vmem32_game; +static int forced_game_region = -1; +static int forced_game_cable = -1; cThread emu_thread(&dc_run, NULL); @@ -133,15 +135,20 @@ void LoadSpecialSettings() { if (settings.platform.system == DC_PLATFORM_DREAMCAST) { - INFO_LOG(BOOT, "Game ID is [%s]", reios_product_number); + char prod_id[sizeof(ip_meta.product_number) + 1] = {0}; + memcpy(prod_id, ip_meta.product_number, sizeof(ip_meta.product_number)); + + NOTICE_LOG(BOOT, "Game ID is [%s]", prod_id); rtt_to_buffer_game = false; safemode_game = false; tr_poly_depth_mask_game = false; extra_depth_game = false; disable_vmem32_game = false; + forced_game_region = -1; + forced_game_cable = -1; - if (reios_windows_ce || settings.dreamcast.ForceWindowsCE - || !strncmp("T26702N", reios_product_number, 7)) // PBA Tour Bowling 2001 + if (ip_meta.isWindowsCE() || settings.dreamcast.ForceWindowsCE + || !strncmp("T26702N", prod_id, 7)) // PBA Tour Bowling 2001 { INFO_LOG(BOOT, "Enabling Full MMU and Extra depth scaling for Windows CE game"); settings.rend.ExtraDepthScale = 0.1; @@ -151,98 +158,151 @@ void LoadSpecialSettings() } // Tony Hawk's Pro Skater 2 - if (!strncmp("T13008D", reios_product_number, 7) || !strncmp("T13006N", reios_product_number, 7) + if (!strncmp("T13008D", prod_id, 7) || !strncmp("T13006N", prod_id, 7) // Tony Hawk's Pro Skater 1 - || !strncmp("T40205N", reios_product_number, 7) + || !strncmp("T40205N", prod_id, 7) // Tony Hawk's Skateboarding - || !strncmp("T40204D", reios_product_number, 7) + || !strncmp("T40204D", prod_id, 7) // Skies of Arcadia - || !strncmp("MK-51052", reios_product_number, 8) + || !strncmp("MK-51052", prod_id, 8) // Eternal Arcadia (JP) - || !strncmp("HDR-0076", reios_product_number, 8) + || !strncmp("HDR-0076", prod_id, 8) // Flag to Flag (US) - || !strncmp("MK-51007", reios_product_number, 8) + || !strncmp("MK-51007", prod_id, 8) // Super Speed Racing (JP) - || !strncmp("HDR-0013", reios_product_number, 8) + || !strncmp("HDR-0013", prod_id, 8) // Yu Suzuki Game Works Vol. 1 - || !strncmp("6108099", reios_product_number, 7) + || !strncmp("6108099", prod_id, 7) // L.O.L - || !strncmp("T2106M", reios_product_number, 6) + || !strncmp("T2106M", prod_id, 6) // Miss Moonlight - || !strncmp("T18702M", reios_product_number, 7) + || !strncmp("T18702M", prod_id, 7) // Tom Clancy's Rainbow Six (US) - || !strncmp("T40401N", reios_product_number, 7) + || !strncmp("T40401N", prod_id, 7) // Tom Clancy's Rainbow Six incl. Eagle Watch Missions (EU) - || !strncmp("T-45001D05", reios_product_number, 10)) + || !strncmp("T-45001D05", prod_id, 10)) { + INFO_LOG(BOOT, "Enabling render to texture buffer for game %s", prod_id); settings.rend.RenderToTextureBuffer = 1; rtt_to_buffer_game = true; } - if (!strncmp("HDR-0176", reios_product_number, 8) || !strncmp("RDC-0057", reios_product_number, 8)) + if (!strncmp("HDR-0176", prod_id, 8) || !strncmp("RDC-0057", prod_id, 8)) { + INFO_LOG(BOOT, "Enabling translucent depth multipass for game %s", prod_id); // Cosmic Smash settings.rend.TranslucentPolygonDepthMask = 1; tr_poly_depth_mask_game = true; } // Demolition Racer - if (!strncmp("T15112N", reios_product_number, 7) + if (!strncmp("T15112N", prod_id, 7) // Ducati World - Racing Challenge (NTSC) - || !strncmp("T-8113N", reios_product_number, 7) + || !strncmp("T-8113N", prod_id, 7) // Ducati World (PAL) - || !strncmp("T-8121D-50", reios_product_number, 10)) + || !strncmp("T-8121D-50", prod_id, 10)) { - INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", reios_product_number); + INFO_LOG(BOOT, "Enabling Dynarec safe mode for game %s", prod_id); settings.dynarec.safemode = 1; safemode_game = true; } // NHL 2K2 - if (!strncmp("MK-51182", reios_product_number, 8)) + if (!strncmp("MK-51182", prod_id, 8)) { - INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id); settings.rend.ExtraDepthScale = 10000; extra_depth_game = true; } // Re-Volt (US, EU) - else if (!strncmp("T-8109N", reios_product_number, 7) || !strncmp("T8107D 50", reios_product_number, 10)) + else if (!strncmp("T-8109N", prod_id, 7) || !strncmp("T8107D 50", prod_id, 10)) { - INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", reios_product_number); + INFO_LOG(BOOT, "Enabling Extra depth scaling for game %s", prod_id); settings.rend.ExtraDepthScale = 100; extra_depth_game = true; } // Super Producers - if (!strncmp("T14303M", reios_product_number, 7) + if (!strncmp("T14303M", prod_id, 7) // Giant Killers - || !strncmp("T45401D 50", reios_product_number, 10) + || !strncmp("T45401D 50", prod_id, 10) // Wild Metal (US) - || !strncmp("T42101N 00", reios_product_number, 10) + || !strncmp("T42101N 00", prod_id, 10) // Wild Metal (EU) - || !strncmp("T40501D-50", reios_product_number, 10) + || !strncmp("T40501D-50", prod_id, 10) // Resident Evil 2 (US) - || !strncmp("T1205N", reios_product_number, 6) + || !strncmp("T1205N", prod_id, 6) // Resident Evil 2 (EU) - || !strncmp("T7004D 50", reios_product_number, 10) + || !strncmp("T7004D 50", prod_id, 10) // Rune Jade - || !strncmp("T14304M", reios_product_number, 7) + || !strncmp("T14304M", prod_id, 7) // Marionette Company - || !strncmp("T5202M", reios_product_number, 6) + || !strncmp("T5202M", prod_id, 6) // Marionette Company 2 - || !strncmp("T5203M", reios_product_number, 6) + || !strncmp("T5203M", prod_id, 6) // Maximum Pool (for online support) - || !strncmp("T11010N", reios_product_number, 7) + || !strncmp("T11010N", prod_id, 7) // StarLancer (US) (for online support) - || !strncmp("T40209N", reios_product_number, 7) + || !strncmp("T40209N", prod_id, 7) // StarLancer (EU) (for online support) - || !strncmp("T17723D 05", reios_product_number, 10) + || !strncmp("T17723D 05", prod_id, 10) ) { - INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", reios_product_number); + INFO_LOG(BOOT, "Disabling 32-bit virtual memory for game %s", prod_id); settings.dynarec.disable_vmem32 = true; disable_vmem32_game = true; } + std::string areas(ip_meta.area_symbols, sizeof(ip_meta.area_symbols)); + bool region_usa = areas.find('U') != std::string::npos; + bool region_eu = areas.find('E') != std::string::npos; + bool region_japan = areas.find('J') != std::string::npos; + if (region_usa || region_eu || region_japan) + { + switch (settings.dreamcast.region) + { + case 0: // Japan + if (!region_japan) + { + NOTICE_LOG(BOOT, "Japan region not supported. Using %s instead", region_usa ? "USA" : "Europe"); + settings.dreamcast.region = region_usa ? 1 : 2; + forced_game_region = settings.dreamcast.region; + } + break; + case 1: // USA + if (!region_usa) + { + NOTICE_LOG(BOOT, "USA region not supported. Using %s instead", region_eu ? "Europe" : "Japan"); + settings.dreamcast.region = region_eu ? 2 : 0; + forced_game_region = settings.dreamcast.region; + } + break; + case 2: // Europe + if (!region_eu) + { + NOTICE_LOG(BOOT, "Europe region not supported. Using %s instead", region_usa ? "USA" : "Japan"); + settings.dreamcast.region = region_usa ? 1 : 0; + forced_game_region = settings.dreamcast.region; + } + break; + case 3: // Default + if (region_usa) + settings.dreamcast.region = 1; + else if (region_eu) + settings.dreamcast.region = 2; + else + settings.dreamcast.region = 0; + forced_game_region = settings.dreamcast.region; + break; + } + } + else + WARN_LOG(BOOT, "No region specified in IP.BIN"); + if (settings.dreamcast.cable <= 1 && !ip_meta.supportsVGA()) + { + NOTICE_LOG(BOOT, "Game doesn't support VGA. Using TV Composite instead"); + settings.dreamcast.cable = 3; + forced_game_cable = settings.dreamcast.cable; + } } else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE) { - INFO_LOG(BOOT, "Game ID is [%s]", naomi_game_id); + NOTICE_LOG(BOOT, "Game ID is [%s]", naomi_game_id); if (!strcmp("METAL SLUG 6", naomi_game_id) || !strcmp("WAVE RUNNER GP", naomi_game_id)) { @@ -491,6 +551,7 @@ void dc_start_game(const char *path) if (DiscSwap()) LoadCustom(); } + FixUpFlash(); } else if (settings.platform.system == DC_PLATFORM_NAOMI || settings.platform.system == DC_PLATFORM_ATOMISWAVE) { @@ -787,7 +848,11 @@ void LoadCustom() char *reios_id; if (settings.platform.system == DC_PLATFORM_DREAMCAST) { - reios_id = reios_disk_id(); + static char _disk_id[sizeof(ip_meta.product_number) + 1]; + + reios_disk_id(); + memcpy(_disk_id, ip_meta.product_number, sizeof(ip_meta.product_number)); + reios_id = _disk_id; char *p = reios_id + strlen(reios_id) - 1; while (p >= reios_id && *p == ' ') @@ -813,8 +878,10 @@ void LoadCustom() void SaveSettings() { cfgSaveBool("config", "Dynarec.Enabled", settings.dynarec.Enable); - cfgSaveInt("config", "Dreamcast.Cable", settings.dreamcast.cable); - cfgSaveInt("config", "Dreamcast.Region", settings.dreamcast.region); + if (forced_game_cable == -1 || forced_game_cable != settings.dreamcast.cable) + cfgSaveInt("config", "Dreamcast.Cable", settings.dreamcast.cable); + if (forced_game_region == -1 || forced_game_region != settings.dreamcast.region) + cfgSaveInt("config", "Dreamcast.Region", settings.dreamcast.region); cfgSaveInt("config", "Dreamcast.Broadcast", settings.dreamcast.broadcast); cfgSaveBool("config", "Dreamcast.ForceWindowsCE", settings.dreamcast.ForceWindowsCE); cfgSaveBool("config", "Dynarec.idleskip", settings.dynarec.idleskip); diff --git a/core/reios/gdrom_hle.cpp b/core/reios/gdrom_hle.cpp index a9c0b5da5..48ae5bd10 100644 --- a/core/reios/gdrom_hle.cpp +++ b/core/reios/gdrom_hle.cpp @@ -630,7 +630,7 @@ void gdrom_hle_op() // // Returns: zero if successful, nonzero if failure WriteMem32(r[4] + 0, (gd_hle_state.status == BIOS_DATA_AVAIL || SecNumber.Status == GD_PLAY) ? 3 : 1); - if (strstr(reios_device_info, "GD-ROM") != NULL) + if (memcmp(ip_meta.disk_type, "GD-ROM", sizeof(ip_meta.disk_type)) == 0) WriteMem32(r[4] + 4, GdRom); else WriteMem32(r[4] + 4, libGDR_GetDiscType()); diff --git a/core/reios/reios.cpp b/core/reios/reios.cpp index 39b7f3aab..265d56cf6 100644 --- a/core/reios/reios.cpp +++ b/core/reios/reios.cpp @@ -66,7 +66,7 @@ static u32 decode_iso733(iso733_t v) | ((v >> 8) & 0xFF000000); } -static bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") +static bool reios_locate_bootfile(const char* bootfile) { reios_pre_init(); @@ -151,44 +151,21 @@ static bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") return false; } -char reios_hardware_id[17]; -char reios_maker_id[17]; -char reios_device_info[17]; -char reios_area_symbols[9]; -char reios_peripherals[9]; -char reios_product_number[11]; -char reios_product_version[7]; -char reios_releasedate[17]; -char reios_boot_filename[17]; -char reios_software_company[17]; -char reios_software_name[129]; -char reios_bootfile[32]; -bool reios_windows_ce = false; +ip_meta_t ip_meta; -char* reios_disk_id() { +void reios_disk_id() { reios_pre_init(); u8 buf[2048]; libGDR_ReadSector(buf, base_fad, 1, sizeof(buf)); - memcpy(&reios_hardware_id[0], &buf[0], 16 * sizeof(char)); - memcpy(&reios_maker_id[0], &buf[16], 16 * sizeof(char)); - memcpy(&reios_device_info[0], &buf[32], 16 * sizeof(char)); - memcpy(&reios_area_symbols[0], &buf[48], 8 * sizeof(char)); - memcpy(&reios_peripherals[0], &buf[56], 8 * sizeof(char)); - memcpy(&reios_product_number[0], &buf[64], 10 * sizeof(char)); - memcpy(&reios_product_version[0], &buf[74], 6 * sizeof(char)); - memcpy(&reios_releasedate[0], &buf[80], 16 * sizeof(char)); - memcpy(&reios_boot_filename[0], &buf[96], 16 * sizeof(char)); - memcpy(&reios_software_company[0], &buf[112], 16 * sizeof(char)); - memcpy(&reios_software_name[0], &buf[128], 128 * sizeof(char)); - reios_windows_ce = memcmp("0WINCEOS.BIN", &reios_boot_filename[0], 12) == 0; - INFO_LOG(REIOS, "hardware %.16s maker %.16s device %.16s area %.8s periph %.8s product %.10s version %.6s date %.16s boot %.16s softco %.16s name %.128s", - reios_hardware_id, reios_maker_id, reios_device_info, reios_area_symbols, - reios_peripherals, reios_product_number, reios_product_version, - reios_releasedate, reios_boot_filename, reios_software_company, reios_software_name); - - return reios_product_number; + memcpy(&ip_meta, buf, sizeof(ip_meta)); + INFO_LOG(REIOS, "hardware %.16s maker %.16s ks %.5s type %.6s num %.5s area %.8s ctrl %.4s dev %c vga %c wince %c " + "product %.10s version %.6s date %.8s boot %.16s softco %.16s name %.128s", + ip_meta.hardware_id, ip_meta.maker_id, ip_meta.ks, ip_meta.disk_type, ip_meta.disk_num, ip_meta.area_symbols, + ip_meta.ctrl, ip_meta.dev, ip_meta.vga, ip_meta.wince, + ip_meta.product_number, ip_meta.product_version, + ip_meta.release_date, ip_meta.boot_filename, ip_meta.software_company, ip_meta.software_name); } static void reios_sys_system() { @@ -630,7 +607,7 @@ static void reios_boot() setup_syscall(hook_addr(&reios_sys_gd2), dc_bios_syscall_gd2); setup_syscall(hook_addr(&reios_sys_misc), dc_bios_syscall_misc); - //Infinitive loop for arm ! + //Infinite loop for arm ! WriteMem32(0x80800000, 0xEAFFFFFE); if (settings.reios.ElfFile.size()) { @@ -640,9 +617,12 @@ static void reios_boot() reios_setup_state(0x8C010000); } else { - if (settings.platform.system == DC_PLATFORM_DREAMCAST) { - if (reios_boot_filename[0] == '\0' || !reios_locate_bootfile(reios_boot_filename)) - msgboxf("Failed to locate bootfile %s", MBX_ICONERROR, reios_boot_filename); + if (settings.platform.system == DC_PLATFORM_DREAMCAST) + { + char bootfile[sizeof(ip_meta.boot_filename) + 1] = {0}; + memcpy(bootfile, ip_meta.boot_filename, sizeof(ip_meta.boot_filename)); + if (bootfile[0] == '\0' || !reios_locate_bootfile(bootfile)) + msgboxf("Failed to locate bootfile %s", MBX_ICONERROR, bootfile); reios_setup_state(0xac008300); } else { diff --git a/core/reios/reios.h b/core/reios/reios.h index 4b7c08dee..58734e241 100644 --- a/core/reios/reios.h +++ b/core/reios/reios.h @@ -12,11 +12,33 @@ void reios_term(); void DYNACALL reios_trap(u32 op); -char* reios_disk_id(); -extern char reios_device_info[17]; -extern char reios_software_name[129]; -extern char reios_product_number[11]; -extern bool reios_windows_ce; +void reios_disk_id(); + +struct ip_meta_t +{ + char hardware_id[16]; + char maker_id[16]; + char ks[5]; + char disk_type[6]; + char disk_num[5]; + char area_symbols[8]; + char ctrl[4]; + char dev; + char vga; + char wince; + char _unk1; + char product_number[10]; + char product_version[6]; + char release_date[8]; + char _unk2[8]; + char boot_filename[16]; + char software_company[16]; + char software_name[128]; + + bool isWindowsCE() { return wince == '1' || memcmp("0WINCEOS.BIN", boot_filename, 12) == 0; } + bool supportsVGA() { return vga == '1'; } +}; +extern ip_meta_t ip_meta; #define REIOS_OPCODE 0x085B diff --git a/core/rend/gles/CustomTexture.cpp b/core/rend/gles/CustomTexture.cpp index 270cef23b..d36bd2e82 100644 --- a/core/rend/gles/CustomTexture.cpp +++ b/core/rend/gles/CustomTexture.cpp @@ -82,7 +82,7 @@ void CustomTexture::LoaderThread() std::string CustomTexture::GetGameId() { - std::string game_id = reios_product_number; + std::string game_id(ip_meta.product_number, sizeof(ip_meta.product_number)); const size_t str_end = game_id.find_last_not_of(" "); if (str_end == std::string::npos) return "";