From ea57147dbb3a1b8913ebb625e472e779176d7b28 Mon Sep 17 00:00:00 2001 From: eadmaster <925171+eadmaster@users.noreply.github.com> Date: Thu, 5 Feb 2026 10:30:00 +0100 Subject: [PATCH 1/4] added ROM memory region --- libretro-common/include/libretro.h | 3 +++ libretro.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index cb1c2d25..7d445309 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -322,6 +322,9 @@ enum retro_language /* Video ram lets a frontend peek into a game systems video RAM (VRAM). */ #define RETRO_MEMORY_VIDEO_RAM 3 +/* ROM lets a frontend peek into a game systems ROM. */ +#define RETRO_MEMORY_ROM 4 + /* Keysyms used for ID in input state callback when polling RETRO_KEYBOARD. */ enum retro_key { diff --git a/libretro.cpp b/libretro.cpp index a3ba3e3b..6ea90c0b 100644 --- a/libretro.cpp +++ b/libretro.cpp @@ -2615,6 +2615,8 @@ void *retro_get_memory_data(unsigned type) return BaseRAM; case RETRO_MEMORY_VIDEO_RAM: return vdc->VRAM; + case RETRO_MEMORY_ROM: + return ROMSpace; default: break; } @@ -2634,6 +2636,8 @@ size_t retro_get_memory_size(unsigned type) return 8192; case RETRO_MEMORY_VIDEO_RAM: return 65536; + case RETRO_MEMORY_ROM: + return (0x88 * 8192 + 8192); // TODO: dynamic based on loaded content? default: break; } From a31d43ddcf39712320ec4d2772d9cc4109641622 Mon Sep 17 00:00:00 2001 From: eadmaster <925171+eadmaster@users.noreply.github.com> Date: Sat, 28 Feb 2026 06:44:23 +0100 Subject: [PATCH 2/4] new optimizations for volume hacks --- mednafen/pce_fast/psg.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mednafen/pce_fast/psg.cpp b/mednafen/pce_fast/psg.cpp index 7b214d32..fa64b1a2 100644 --- a/mednafen/pce_fast/psg.cpp +++ b/mednafen/pce_fast/psg.cpp @@ -35,7 +35,7 @@ void PCEFast_PSG::SetChannelUserVolume(int chnum, int32 new_volume) { if(chnum >=6 || new_volume > 100) return; // check valid args psg_channel *ch = &channel[chnum]; - ch->user_volume = new_volume; + ch->user_volume = (new_volume << 16) / 100; // approx 1/100 } void PCEFast_PSG::UpdateOutput_Norm(const int32 timestamp, psg_channel *ch) @@ -48,10 +48,10 @@ void PCEFast_PSG::UpdateOutput_Norm(const int32 timestamp, psg_channel *ch) samp[0] = dbtable[ch->vl[0]][sv]; samp[1] = dbtable[ch->vl[1]][sv]; - if(ch->user_volume < 100) + if(ch->user_volume < 65536) { - delta0 = (samp[0] - ch->blip_prev_samp[0]) * ch->user_volume / 100; - delta1 = (samp[1] - ch->blip_prev_samp[1]) * ch->user_volume / 100; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; @@ -74,10 +74,10 @@ void PCEFast_PSG::UpdateOutput_Noise(const int32 timestamp, psg_channel *ch) samp[0] = dbtable[ch->vl[0]][sv]; samp[1] = dbtable[ch->vl[1]][sv]; - if(ch->user_volume < 100) + if(ch->user_volume < 65536) { - delta0 = (samp[0] - ch->blip_prev_samp[0]) * ch->user_volume / 100; - delta1 = (samp[1] - ch->blip_prev_samp[1]) * ch->user_volume / 100; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; @@ -98,10 +98,10 @@ void PCEFast_PSG::UpdateOutput_Off(const int32 timestamp, psg_channel *ch) samp[0] = samp[1] = 0; - if(ch->user_volume < 100) + if(ch->user_volume < 65536) { - delta0 = (samp[0] - ch->blip_prev_samp[0]) * ch->user_volume / 100; - delta1 = (samp[1] - ch->blip_prev_samp[1]) * ch->user_volume / 100; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; @@ -124,10 +124,10 @@ void PCEFast_PSG::UpdateOutput_Accum(const int32 timestamp, psg_channel *ch) samp[0] = ((int32)dbtable_volonly[ch->vl[0]] * ((int32)ch->samp_accum - 496)) >> (8 + 5); samp[1] = ((int32)dbtable_volonly[ch->vl[1]] * ((int32)ch->samp_accum - 496)) >> (8 + 5); - if(ch->user_volume < 100) + if(ch->user_volume < 65536) { - delta0 = (samp[0] - ch->blip_prev_samp[0]) * ch->user_volume / 100; - delta1 = (samp[1] - ch->blip_prev_samp[1]) * ch->user_volume / 100; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; From 9948699e5b3cee9154c5b110b998c07860088306 Mon Sep 17 00:00:00 2001 From: eadmaster <925171+eadmaster@users.noreply.github.com> Date: Wed, 4 Mar 2026 00:04:02 +0100 Subject: [PATCH 3/4] safer bit shifting for volume scaling --- mednafen/pce_fast/psg.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mednafen/pce_fast/psg.cpp b/mednafen/pce_fast/psg.cpp index fa64b1a2..68870ae9 100644 --- a/mednafen/pce_fast/psg.cpp +++ b/mednafen/pce_fast/psg.cpp @@ -35,7 +35,7 @@ void PCEFast_PSG::SetChannelUserVolume(int chnum, int32 new_volume) { if(chnum >=6 || new_volume > 100) return; // check valid args psg_channel *ch = &channel[chnum]; - ch->user_volume = (new_volume << 16) / 100; // approx 1/100 + ch->user_volume = new_volume; } void PCEFast_PSG::UpdateOutput_Norm(const int32 timestamp, psg_channel *ch) @@ -48,10 +48,10 @@ void PCEFast_PSG::UpdateOutput_Norm(const int32 timestamp, psg_channel *ch) samp[0] = dbtable[ch->vl[0]][sv]; samp[1] = dbtable[ch->vl[1]][sv]; - if(ch->user_volume < 65536) + if(ch->user_volume < 100) { - delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; - delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume * 164) >> 14; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume * 164) >> 14; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; @@ -74,10 +74,10 @@ void PCEFast_PSG::UpdateOutput_Noise(const int32 timestamp, psg_channel *ch) samp[0] = dbtable[ch->vl[0]][sv]; samp[1] = dbtable[ch->vl[1]][sv]; - if(ch->user_volume < 65536) + if(ch->user_volume < 100) { - delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; - delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume * 164) >> 14; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume * 164) >> 14; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; @@ -98,10 +98,10 @@ void PCEFast_PSG::UpdateOutput_Off(const int32 timestamp, psg_channel *ch) samp[0] = samp[1] = 0; - if(ch->user_volume < 65536) + if(ch->user_volume < 100) { - delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; - delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume * 164) >> 14; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume * 164) >> 14; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; @@ -124,10 +124,10 @@ void PCEFast_PSG::UpdateOutput_Accum(const int32 timestamp, psg_channel *ch) samp[0] = ((int32)dbtable_volonly[ch->vl[0]] * ((int32)ch->samp_accum - 496)) >> (8 + 5); samp[1] = ((int32)dbtable_volonly[ch->vl[1]] * ((int32)ch->samp_accum - 496)) >> (8 + 5); - if(ch->user_volume < 65536) + if(ch->user_volume < 100) { - delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume) >> 16; - delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume) >> 16; + delta0 = ((samp[0] - ch->blip_prev_samp[0]) * ch->user_volume * 164) >> 14; + delta1 = ((samp[1] - ch->blip_prev_samp[1]) * ch->user_volume * 164) >> 14; } else { delta0 = samp[0] - ch->blip_prev_samp[0]; delta1 = samp[1] - ch->blip_prev_samp[1]; From 958d7d80c4946c12bba4f3d672b345fd1c0b412c Mon Sep 17 00:00:00 2001 From: eadmaster <925171+eadmaster@users.noreply.github.com> Date: Fri, 6 Mar 2026 20:05:57 +0100 Subject: [PATCH 4/4] added core option to ignore cd edc errors --- libretro.cpp | 10 ++++++++++ libretro_core_options.h | 15 +++++++++++++++ mednafen/pce_fast/pcecd_drive.cpp | 9 ++++++++- mednafen/pce_fast/pcecd_drive.h | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/libretro.cpp b/libretro.cpp index 6ea90c0b..54a9408a 100644 --- a/libretro.cpp +++ b/libretro.cpp @@ -1873,6 +1873,16 @@ static void check_variables(bool first_run) do_cdsettings = true; setting_pce_fast_cdpsgvolume = atoi(var.value); } + + var.key = "pce_fast_cdignoreerrors"; + setting_pce_fast_cdignoreerrors = false; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + if (strcmp(var.value, "enabled") == 0) + { + setting_pce_fast_cdignoreerrors = true; + } + var.key = "pce_fast_cdspeed"; diff --git a/libretro_core_options.h b/libretro_core_options.h index 7710f29f..0066081b 100644 --- a/libretro_core_options.h +++ b/libretro_core_options.h @@ -731,6 +731,21 @@ struct retro_core_option_v2_definition option_defs_us[] = { }, "100" }, + { + "pce_fast_cdignoreerrors", + "CD Ignore EDC/L-EC Errors", + NULL, + "Ignore EDC/L-EC errors. Needed for compatibility with some hacks.", + NULL, + "cd", + { + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, + }, + "disabled" + }, + { "pce_fast_nospritelimit", "No Sprite Limit", diff --git a/mednafen/pce_fast/pcecd_drive.cpp b/mednafen/pce_fast/pcecd_drive.cpp index d31451e4..4701d038 100644 --- a/mednafen/pce_fast/pcecd_drive.cpp +++ b/mednafen/pce_fast/pcecd_drive.cpp @@ -158,6 +158,8 @@ static int32 CDReadTimer; static uint32 SectorAddr; static uint32 SectorCount; +bool setting_pce_fast_cdignoreerrors; + enum { @@ -412,7 +414,12 @@ static void CommandCCError(int key, int asc = 0, int ascq = 0) static bool ValidateRawDataSector(uint8 *data, const uint32 lba) { - if(!edc_lec_check_and_correct(data, false)) + bool c = edc_lec_check_and_correct(data, false); + + //if(!c) + // printf("failed ValidateRawDataSector: %x\n", lba); + + if(!c && !setting_pce_fast_cdignoreerrors) { din.Flush(); cd.data_transfer_done = false; diff --git a/mednafen/pce_fast/pcecd_drive.h b/mednafen/pce_fast/pcecd_drive.h index 1d684c98..26a55e9f 100644 --- a/mednafen/pce_fast/pcecd_drive.h +++ b/mednafen/pce_fast/pcecd_drive.h @@ -16,6 +16,7 @@ struct pcecd_drive_bus_t }; extern pcecd_drive_bus_t cd_bus; // Don't access this structure directly by name outside of pcecd_drive.c, but use the macros below. +extern bool setting_pce_fast_cdignoreerrors; // Signals under our(the "target") control. #define PCECD_Drive_IO_mask 0x001