From 3945353db8fa505f4d6d2f554dcdddfc18f44b72 Mon Sep 17 00:00:00 2001 From: pceDev16 <95596143+pceDev16@users.noreply.github.com> Date: Sat, 18 Nov 2023 17:17:23 -0800 Subject: [PATCH 01/14] Update README_macOS_compile.md Update compilation instructions for X86_64 and ARM64 --- README_macOS_compile.md | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/README_macOS_compile.md b/README_macOS_compile.md index fe451ba..5a51949 100644 --- a/README_macOS_compile.md +++ b/README_macOS_compile.md @@ -14,35 +14,23 @@ Get Xcode Command Line tools: xcode-select --install ``` -We have confirmed a successful Mednafen build on macOS Monterey running on both Intel(x86_64) and Apple silicon M1(ARM64) architectures and will provide instructions accordingly. +We have confirmed a successful Mednafen build on macOS Monterey and higher running on both Intel(x86_64) and Apple silicon M1(ARM64) architectures. -For a native Intel(x86_64) build we will use "Homebrew" to pull in the needed Mednafen dependencies: +For a native Intel(x86_64) or Apple Silicon(ARM64) build we will use "Homebrew" to pull in the needed Mednafen dependencies: ``` brew install pkg-config gettext sdl2 libsndfile jack lzo zstd ``` -**Optional Note:** There is currently an SDL issue with newer SDL2 Brew (2.0.22+) installs that can cause Mednafen to "hang" when exiting due to the SDL Audio close function having changed. To work around this make sure to use the 2.0.22 SDL2 Brew install. - -**Update 04/2023:** SDL 2.26.4(SDL-release-2.26.4-0-g07d0f51fa) no longer seems to exhibit this behaviour so we will mark the below as optional in case you are seeing the "hanging" behaviour upon exiting Mednafen. -``` -wget https://github.com/Homebrew/homebrew-core/raw/5c1cf00f7540d9cf0344c0bac4aabe4e5a7fa8a5/Formula/sdl2.rb -brew install --build-from-source sdl2.rb -``` - -For a native Apple silicon M1(ARM64) build we will have to use "MacPorts" in order to get the correct Mednafen dependencies to build: -``` -sudo port -N install pkgconfig clang-14 libiconv libsdl2 libcdio gettext libsndfile libmpcdec zlib -``` - ### Compilation Commands -Mednafen's build process makes use of 'configure' in order to set up environment-specific options in preparation -for the compile; the below instructions to build Mednafen will attempt to use all of your machine's threads when compiling as the compilation process can take up quite some time, the procedure is as follows : +Mednafen's build process makes use of 'configure' in order to set up environment-specific options in preparation for the compile. + +The below instructions to build Mednafen will attempt to use all of your machine's threads when compiling as the compilation process can take up quite some time, we disable optimization for the build as Mednafen has proven quite unstable when attempting to have the clang compiler on macOS optimize the application. The compilation procedure is as follows: ``` ./configure --enable-ss -make -j `sysctl -n hw.logicalcpu` +make CFLAGS='-g -w' CXXFLAGS='-g -w' -j `sysctl -n hw.logicalcpu` ``` At this point, the Mednafen binary can be found in the mednafen/src/ folder; you may manually copy/move it From f3a5d133fe736d927252a2e83cc3838cc3722b6c Mon Sep 17 00:00:00 2001 From: David Shadoff Date: Mon, 20 Nov 2023 21:47:32 -0500 Subject: [PATCH 02/14] Fix BRAM re-lock ( issue #111 ) --- mednafen/src/pce/pcecd.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mednafen/src/pce/pcecd.cpp b/mednafen/src/pce/pcecd.cpp index 5ab47e3..34244fb 100644 --- a/mednafen/src/pce/pcecd.cpp +++ b/mednafen/src/pce/pcecd.cpp @@ -744,10 +744,13 @@ MDFN_FASTCALL int32 PCECD_Write(uint32 timestamp, uint32 physAddr, uint8 data) break; case 0x7: // $1807: D7=1 enables backup ram - if (data & 0x80) - { - bBRAMEnabled = true; - } + + bBRAMEnabled = (data & 0x80) ? true : false; + + //if (data & 0x80) + //{ + // bBRAMEnabled = true; + //} break; case 0x8: // Set ADPCM address low From f0f81ea7873611b3e4ffdb577373a0291a118454 Mon Sep 17 00:00:00 2001 From: David Shadoff Date: Mon, 20 Nov 2023 22:09:29 -0500 Subject: [PATCH 03/14] Update pcecd.cpp --- mednafen/src/pce/pcecd.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mednafen/src/pce/pcecd.cpp b/mednafen/src/pce/pcecd.cpp index 34244fb..ba36f25 100644 --- a/mednafen/src/pce/pcecd.cpp +++ b/mednafen/src/pce/pcecd.cpp @@ -746,11 +746,6 @@ MDFN_FASTCALL int32 PCECD_Write(uint32 timestamp, uint32 physAddr, uint8 data) case 0x7: // $1807: D7=1 enables backup ram bBRAMEnabled = (data & 0x80) ? true : false; - - //if (data & 0x80) - //{ - // bBRAMEnabled = true; - //} break; case 0x8: // Set ADPCM address low From 1efefe7b0dda15d934a54662826e4152cdef70f3 Mon Sep 17 00:00:00 2001 From: pceDev16 <95596143+pceDev16@users.noreply.github.com> Date: Fri, 24 Nov 2023 09:39:31 -0800 Subject: [PATCH 04/14] Update configure.ac to reflect 1.29.0.pceDev-1.2 release Update configure.ac to reflect 1.29.0.pceDev-1.2 release --- mednafen/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mednafen/configure.ac b/mednafen/configure.ac index 35ca4de..521a898 100644 --- a/mednafen/configure.ac +++ b/mednafen/configure.ac @@ -6,7 +6,7 @@ AC_CONFIG_MACRO_DIR([m4]) # # Avoid trailing and leading zeroes in the decimal version components to avoid confusing not-so-learned people. # -MEDNAFEN_VERSION="1.29.0.pceDev-1.1 (`git log -1 --format=format:%h`) built on `date` " +MEDNAFEN_VERSION="1.29.0.pceDev-1.2 (`git log -1 --format=format:%h`) built on `date` " MEDNAFEN_VERSION_NUMERIC=0x00102900 # 0xJJJnnnRR From a9a57df49a2ccbeca3dc5fea1a7cc13decd5440b Mon Sep 17 00:00:00 2001 From: pceDev16 <95596143+pceDev16@users.noreply.github.com> Date: Fri, 24 Nov 2023 10:51:06 -0800 Subject: [PATCH 05/14] Update configure to prepare for 1.2 Release --- mednafen/configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mednafen/configure b/mednafen/configure index 24eccf1..d8cb8e9 100755 --- a/mednafen/configure +++ b/mednafen/configure @@ -4393,7 +4393,7 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } # # Avoid trailing and leading zeroes in the decimal version components to avoid confusing not-so-learned people. # -MEDNAFEN_VERSION="1.29.0.pceDev-1.1 (`git log -1 --format=format:%h`) built on `date` " +MEDNAFEN_VERSION="1.29.0.pceDev-1.2 (`git log -1 --format=format:%h`) built on `date` " MEDNAFEN_VERSION_NUMERIC=0x00102900 # 0xJJJnnnRR From 6f3928d5d52392582af09ba2e78cc32975794330 Mon Sep 17 00:00:00 2001 From: pceDev16 <95596143+pceDev16@users.noreply.github.com> Date: Fri, 24 Nov 2023 11:13:03 -0800 Subject: [PATCH 06/14] Update RELEASE_NOTES.md Updating for 1.2 Release --- RELEASE_NOTES.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 24564ee..f8a8f09 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,28 @@ # Release Notes +## New release 1.2 2023/11/24 + +### New Features/Improvements: + +#### PC-FX Improvements / BugFixes: + - Adds Azerty Keyboard support for Debugging functions + - Improve PC-FX palette editor - In debug mode, change PC-FX palette editor to show 16-bit values, with a colour swatch in the right-hand side to demonstrate actual colour (based on YUV) + - PSG Tweaks Update channel 1 frequency cache upon LFO frequency register writes (the way the channel 1 frequency and LFO frequency are combined is still inaccurate, however, causing frequency update timing granularity to be too high). Ported over MDFN 1.31.0 release + +#### PC-Engine Improvements / Bugfixes: +- PSG Tweaks Update channel 1 frequency cache upon LFO frequency register writes (the way the channel 1 frequency and LFO frequency are combined is still inaccurate, however, causing frequency update timing granularity to be too high). Ported over MDFN 1.31.0 release +- Backup Memory Lock-bit fix - While the backup memory lock bits inhibit writing to backup memory, the behaviour on the real machine also protects the memory from being read. This commit makes the emulator function more like the real machine +- Remove Incorrect IRQ Acknowledgement scenario: TIMER interrupt is supposed to be acknowledged by write to $1403. Original code was also acknowledging it on reads from $1402, which was not supported by official documentation. +- Fix junk appearing on PCE Debug palette screen +- Change Default gamesave name removing hash value for BRAM retention and compatbilty when doing PCE dev builds +- Fix improper CDROM BRAM locking in debugger +- PC Engine music player VU meter shows incorrect channels +- BRAM unlock bit should be able to re-lock: Backup memory unlock bit (0x1807 bit 7) is set to unlock BRAM (i.e. set 0x1807 = 0x80). Normally, BRAM is re-locked by reading 0x1803, but can also be locked by resetting bit of 0x1807 (i.e. same as above but the bit is reset) +- Add CI builds for Windows / Linux + +#### Other items: + - This release also contains several Wonderswan module updates that improve emulation accuracy + ## New release 1.1 2022/08/21 ### New Features/Improvements: From 04fb88808bc8c05b99b1eaae6823293406930994 Mon Sep 17 00:00:00 2001 From: pceDev16 <95596143+pceDev16@users.noreply.github.com> Date: Fri, 24 Nov 2023 11:13:47 -0800 Subject: [PATCH 07/14] Update README.md Update to reflect correct date --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e72fc28..30d725b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This is a curated and Community managed Mednafen
GitHub repo in support of t

It has been specifically created with additional tweaks and fixes in direct
support of the PC-Engine Development community and PCE enthusiasts everywhere.

-Current Release! Mednafen 1.29.0.pceDev-1.2 released on 2022/12/03 +Current Release! Mednafen 1.29.0.pceDev-1.2 released on 2023/11/24

Screenshot showing the various NEW accuracy focussed improvements
made to the scanline rendering, general overscan visibility and VDC display resolution rendering

From 50826e2225a54d3a075bb1a1ce4e7d3941c94dc2 Mon Sep 17 00:00:00 2001 From: pceDev16 <95596143+pceDev16@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:42:15 -0800 Subject: [PATCH 08/14] Update RELEASE_NOTES.md minor updates and rewording for clarification. --- RELEASE_NOTES.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f8a8f09..aeeb1d5 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -11,13 +11,14 @@ #### PC-Engine Improvements / Bugfixes: - PSG Tweaks Update channel 1 frequency cache upon LFO frequency register writes (the way the channel 1 frequency and LFO frequency are combined is still inaccurate, however, causing frequency update timing granularity to be too high). Ported over MDFN 1.31.0 release -- Backup Memory Lock-bit fix - While the backup memory lock bits inhibit writing to backup memory, the behaviour on the real machine also protects the memory from being read. This commit makes the emulator function more like the real machine -- Remove Incorrect IRQ Acknowledgement scenario: TIMER interrupt is supposed to be acknowledged by write to $1403. Original code was also acknowledging it on reads from $1402, which was not supported by official documentation. +- Backup memory visibility was previously inconsistent between HuCard and CDROM, and locking behaviour was not always correct. Now, physical memory at $1EE000 should give the "processor's view" of the memory, depending on lock/unlock status, and "Backup Memory" screen should show the actual data (Note: HuCard startup state is still default 'unlocked' which is not correct). Also, $1807 register writes should be able to re-lock memory +- Remove Incorrect IRQ Acknowledgement scenario: TIMER interrupt is supposed to be acknowledged by write to $1403. Original code was also acknowledging it on reads from $1402, which was not supported by official documentation. - Fix junk appearing on PCE Debug palette screen - Change Default gamesave name removing hash value for BRAM retention and compatbilty when doing PCE dev builds - Fix improper CDROM BRAM locking in debugger - PC Engine music player VU meter shows incorrect channels -- BRAM unlock bit should be able to re-lock: Backup memory unlock bit (0x1807 bit 7) is set to unlock BRAM (i.e. set 0x1807 = 0x80). Normally, BRAM is re-locked by reading 0x1803, but can also be locked by resetting bit of 0x1807 (i.e. same as above but the bit is reset) +- Fix VU Meter display +- Other minor changes to warnings and defaults - Add CI builds for Windows / Linux #### Other items: From 732c773b4ef78bef671ace938aaeb4629fae66df Mon Sep 17 00:00:00 2001 From: David Shadoff Date: Thu, 7 Dec 2023 20:10:32 -0500 Subject: [PATCH 09/14] Add configurable item "pcfx.external_bram_size_kbytes" ( #139 ) Add configurable item (pcfx.external_bram_size_kbytes) to define size of FX-BMP card. Valid values are: 128, 256, 512, 1024, 2048 --- mednafen/src/pcfx/mem-handler.inc | 12 +++---- mednafen/src/pcfx/pcfx.cpp | 53 ++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/mednafen/src/pcfx/mem-handler.inc b/mednafen/src/pcfx/mem-handler.inc index dfbb674..0750ef3 100644 --- a/mednafen/src/pcfx/mem-handler.inc +++ b/mednafen/src/pcfx/mem-handler.inc @@ -91,7 +91,7 @@ static uint8 MDFN_FASTCALL mem_rbyte(v810_timestamp_t ×tamp, uint32 A) return(0xFF); } - return(ExBackupRAM[(A & 0x3FFFF) >> 1]); + return(ExBackupRAM[(A & ((ExBackupSize << 1) -1)) >> 1]); } else if(A >= 0x80000000 && A <= 0x807FFFFF) { @@ -169,7 +169,7 @@ static uint16 MDFN_FASTCALL mem_rhword(v810_timestamp_t ×tamp, uint32 A) return(0xFFFF); } - return(ExBackupRAM[(A & 0x3FFFF) >> 1]); + return(ExBackupRAM[(A & ((ExBackupSize << 1) -1)) >> 1]); } else if(A >= 0xF8000000 && A <= 0xFFEFFFFF) // PIO { @@ -251,8 +251,8 @@ static void MDFN_FASTCALL mem_wbyte(v810_timestamp_t ×tamp, uint32 A, uint8 if(BackupControl & 0x2) { - BackupSignalDirty |= (ExBackupRAM[(A & 0x3FFFF) >> 1] != V); - ExBackupRAM[(A & 0x3FFFF) >> 1] = V; + BackupSignalDirty |= (ExBackupRAM[(A & ((ExBackupSize << 1) -1)) >> 1] != V); + ExBackupRAM[(A & ((ExBackupSize << 1) -1)) >> 1] = V; } } else if(A >= 0xF8000000 && A <= 0xFFEFFFFF) @@ -298,8 +298,8 @@ static void MDFN_FASTCALL mem_whword(v810_timestamp_t ×tamp, uint32 A, uint if(BackupControl & 0x2) { - BackupSignalDirty |= (ExBackupRAM[(A & 0x3FFFF) >> 1] != (uint8)V); - ExBackupRAM[(A & 0x3FFFF) >> 1] = (uint8)V; + BackupSignalDirty |= (ExBackupRAM[(A & ((ExBackupSize << 1) -1)) >> 1] != (uint8)V); + ExBackupRAM[(A & ((ExBackupSize << 1) -1)) >> 1] = (uint8)V; } } else if(A >= 0xF8000000 && A <= 0xFFEFFFFF) diff --git a/mednafen/src/pcfx/pcfx.cpp b/mednafen/src/pcfx/pcfx.cpp index 5458f00..ce63145 100644 --- a/mednafen/src/pcfx/pcfx.cpp +++ b/mednafen/src/pcfx/pcfx.cpp @@ -64,8 +64,10 @@ static bool WantHuC6273 = false; //static VDC *fx_vdc_chips[2]; + +static uint32 ExBackupSize; static uint16 BackupControl; -static uint8 BackupRAM[0x8000], ExBackupRAM[0x20000]; +static uint8 BackupRAM[0x8000], ExBackupRAM[2097152]; static uint8 ExBusReset; // I/O Register at 0x0700 static bool BRAMDisabled; // Cached at game load, don't remove this caching behavior or save game loss may result(if we ever get a GUI). @@ -408,7 +410,7 @@ static void PCFXDBG_GetAddressSpaceBytes(const char *name, uint32 Address, uint3 { while(Length--) { - Address &= 0x1FFFF; + Address &= (ExBackupSize -1); *Buffer = ExBackupRAM[Address]; Address++; Buffer++; @@ -478,8 +480,8 @@ static void PCFXDBG_PutAddressSpaceBytes(const char *name, uint32 Address, uint3 { if(!(Address & 1)) { - BackupSignalDirty |= (ExBackupRAM[(Address & 0x3FFFF) >> 1] != *Buffer); - ExBackupRAM[(Address & 0x3FFFF) >> 1] = *Buffer; + BackupSignalDirty |= (ExBackupRAM[(Address & ((ExBackupSize << 1) -1) ) >> 1] != *Buffer); + ExBackupRAM[(Address & ((ExBackupSize << 1) -1)) >> 1] = *Buffer; } } Address++; @@ -511,7 +513,7 @@ static void PCFXDBG_PutAddressSpaceBytes(const char *name, uint32 Address, uint3 { while(Length--) { - Address &= 0x1FFFF; + Address &= (ExBackupSize -1); BackupSignalDirty |= (ExBackupRAM[Address] != *Buffer); ExBackupRAM[Address] = *Buffer; Address++; @@ -716,14 +718,17 @@ static MDFN_COLD void LoadCommon(std::vector *CDInterfaces) memcpy(BackupRAM + 0x80, BRInit80, sizeof(BRInit80)); - static const uint8 ExBRInit00[] = { 0x24, 0x8A, 0xDF, 0x50, 0x43, 0x46, 0x58, 0x43, 0x61, 0x72, 0x64, 0x80, - 0x00, 0x01, 0x01, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x04, 0xF9, 0x0C, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - static const uint8 ExBRInit80[] = { 0xF9, 0xFF, 0xFF }; - - memcpy(ExBackupRAM + 0x00, ExBRInit00, sizeof(ExBRInit00)); - memcpy(ExBackupRAM + 0x80, ExBRInit80, sizeof(ExBRInit80)); + //static const uint8 ExBRInit00[] = { 0x24, 0x8A, 0xDF, 0x50, 0x43, 0x46, 0x58, 0x43, 0x61, 0x72, 0x64, 0x80, + // 0x00, 0x01, 0x01, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x04, 0xF9, 0x0C, 0x00, + // 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 + // }; + //static const uint8 ExBRInit80[] = { 0xF9, 0xFF, 0xFF }; + // + // Do NOT pre-initialize external memory + // this should be formatted through the use of the BIOS ROM + // + //memcpy(ExBackupRAM + 0x00, ExBRInit00, sizeof(ExBRInit00)); + //memcpy(ExBackupRAM + 0x80, ExBRInit80, sizeof(ExBRInit80)); try { @@ -735,7 +740,6 @@ static MDFN_COLD void LoadCommon(std::vector *CDInterfaces) throw MDFN_Error(0, _("Save game memory file \"%s\" is an incorrect size(%llu bytes). The correct size is %llu bytes."), MDFN_strhumesc(save_path).c_str(), (unsigned long long)fp_size_tmp, (unsigned long long)32768); savefp.read(BackupRAM, 0x8000); -// savefp.read(ExBackupRAM, 0x20000); } catch(MDFN_Error &e) { @@ -746,13 +750,23 @@ static MDFN_COLD void LoadCommon(std::vector *CDInterfaces) // try { + int64 ExSizeKBytes = MDFN_GetSettingI("pcfx.external_bram_size_kbytes"); + if ((ExSizeKBytes != 128) && + (ExSizeKBytes != 256) && + (ExSizeKBytes != 512) && + (ExSizeKBytes != 1024) && + (ExSizeKBytes != 2048)) + throw MDFN_Error(0, _("Error in mednafne.cfg file: 'pcfx.external_bram_size_kbytes' (%ld) must be one of: 128, 256, 512, 1024, 2048"), ExSizeKBytes); + + ExBackupSize = ExSizeKBytes * 1024; + std::string ext_save_path = MDFN_MakeFName(MDFNMKF_FIXEDSAV, 0, MDFN_GetSettingS("pcfx.external_bram_file")); GZFileStream esavefp(ext_save_path, GZFileStream::MODE::READ); const uint64 efp_size_tmp = esavefp.size(); - if(efp_size_tmp != 131072) - throw MDFN_Error(0, _("External save game memory file \"%s\" is an incorrect size(%llu bytes). The correct size is %llu bytes."), MDFN_strhumesc(ext_save_path).c_str(), (unsigned long long)efp_size_tmp, (unsigned long long)131072); - esavefp.read(ExBackupRAM, 0x20000); + if(efp_size_tmp != ExBackupSize) + throw MDFN_Error(0, _("External save game memory file \"%s\" is an incorrect size(%llu bytes). The correct size is %llu bytes."), MDFN_strhumesc(ext_save_path).c_str(), (unsigned long long)efp_size_tmp, (unsigned long long)ExBackupSize); + esavefp.read(ExBackupRAM, ExBackupSize); // } catch(MDFN_Error &e) @@ -967,7 +981,7 @@ static void SaveBackupMemory(void) fp.close(); FileStream fp_e(MDFN_MakeFName(MDFNMKF_FIXEDSAV, 0, MDFN_GetSettingS("pcfx.external_bram_file")), FileStream::MODE_WRITE_INPLACE); - fp_e.write(ExBackupRAM, 0x20000); + fp_e.write(ExBackupRAM, ExBackupSize); fp_e.truncate(fp_e.tell()); fp_e.close(); } @@ -1008,7 +1022,7 @@ static void StateAction(StateMem *sm, const unsigned load, const bool data_only) SFVAR(BackupControl), SFVAR(ExBusReset), SFPTR8(BackupRAM, BRAMDisabled ? 0 : 0x8000, SFORMAT::FORM::NVMEM), - SFPTR8(ExBackupRAM, BRAMDisabled ? 0 : 0x20000, SFORMAT::FORM::NVMEM), + SFPTR8(ExBackupRAM, BRAMDisabled ? 0 : ExBackupSize, SFORMAT::FORM::NVMEM), SFEND }; @@ -1073,6 +1087,7 @@ static const MDFNSetting PCFXSettings[] = { "pcfx.fxscsi", MDFNSF_EMU_STATE | MDFNSF_CAT_PATH, gettext_noop("Path to the FX-SCSI ROM"), gettext_noop("Intended for developers only."), MDFNST_STRING, "0" }, { "pcfx.disable_bram", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Disable internal and external BRAM."), gettext_noop("It is intended for viewing games' error screens that may be different from simple BRAM full and uninitialized BRAM error screens, though it can cause the game to crash outright."), MDFNST_BOOL, "0" }, { "pcfx.external_bram_file", MDFNSF_EMU_STATE | MDFNSF_CAT_PATH, gettext_noop("Path to external Backup Memory file (i.e. FX-BMP cartridge)."), NULL, MDFNST_STRING, "pcfx_fx-bmp.sav" }, + { "pcfx.external_bram_size_kbytes", MDFNSF_EMU_STATE | MDFNSF_CAT_PATH, gettext_noop("Size of external Backup memory file, in kilobytes (i.e. FX-BMP cartridge)."), NULL, MDFNST_UINT, "128", "128", "2048" }, { "pcfx.cdspeed", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE, gettext_noop("Emulated CD-ROM speed."), gettext_noop("Setting the value higher than 2, the default, will decrease loading times in most games by some degree."), MDFNST_UINT, "2", "2", "10" }, { "pcfx.nospritelimit", MDFNSF_NOFLAGS, gettext_noop("Remove 16-sprites-per-scanline hardware limit."), NULL, MDFNST_BOOL, "0" }, From 5334089083a4b713c578878809e74ac211c7b221 Mon Sep 17 00:00:00 2001 From: David Shadoff Date: Tue, 26 Dec 2023 16:49:52 -0500 Subject: [PATCH 10/14] Fix_180x_registers ( #142 ) Do not repeat 0x1800-0f registers (no 'echoes' in other memory locations). Also, treat 0x180e and 0x180f as separate registers (with no behaviour behind them at this time). --- mednafen/src/pce/pcecd.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/mednafen/src/pce/pcecd.cpp b/mednafen/src/pce/pcecd.cpp index ba36f25..d7a18fc 100644 --- a/mednafen/src/pce/pcecd.cpp +++ b/mednafen/src/pce/pcecd.cpp @@ -140,6 +140,9 @@ typedef struct uint8 LastCmd; uint32 SampleFreq; + uint8 Reg0e; + uint8 Reg0f; + uint8 PlayBuffer; uint8 ReadBuffer; int32 ReadPending; @@ -551,8 +554,10 @@ MDFN_FASTCALL uint8 PCECD_Read(uint32 timestamp, uint32 A, int32 &next_event, co if(!PeekMode) PCECD_Run(timestamp); - switch(A & 0xf) + if ((A & 0x1F00) == 0x1800) { + switch(A & 0xff) + { case 0x0: ret = 0; ret |= SCSICD_GetBSY() ? 0x80 : 0x00; @@ -641,6 +646,16 @@ MDFN_FASTCALL uint8 PCECD_Read(uint32 timestamp, uint32 A, int32 &next_event, co case 0xd: ret = ADPCM.LastCmd; break; + + case 0xe: + ret = ADPCM.Reg0e; + break; + + case 0xf: + ret = ADPCM.Reg0f; + break; + + } } } @@ -685,8 +700,10 @@ MDFN_FASTCALL int32 PCECD_Write(uint32 timestamp, uint32 physAddr, uint8 data) PCECD_Run(timestamp); - switch (physAddr & 0xf) + if ((physAddr & 0x1F00) == 0x1800) { + switch (physAddr & 0xff) + { case 0x0: SCSICD_SetSEL(1); SCSICD_Run(timestamp); @@ -828,6 +845,7 @@ MDFN_FASTCALL int32 PCECD_Write(uint32 timestamp, uint32 physAddr, uint8 data) MSM5205.SetSample(0x800); MSM5205.SetSSI(0); + ADPCM.LastCmd = data; break; } @@ -885,6 +903,7 @@ MDFN_FASTCALL int32 PCECD_Write(uint32 timestamp, uint32 physAddr, uint8 data) case 0xe: // Set ADPCM playback rate { + ADPCM.Reg0e = data; uint8 freq = V & 0x0F; ADPCM.SampleFreq = freq; @@ -895,6 +914,7 @@ MDFN_FASTCALL int32 PCECD_Write(uint32 timestamp, uint32 physAddr, uint8 data) break; case 0xf: + ADPCM.Reg0f = data; Fader.Command = V; #ifdef PCECD_DEBUG @@ -920,6 +940,7 @@ MDFN_FASTCALL int32 PCECD_Write(uint32 timestamp, uint32 physAddr, uint8 data) } Fader_SyncWhich(); break; + } } From 2f769129e02956f22d3e16c692a410e32399d69c Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sat, 17 Feb 2024 13:03:17 -0500 Subject: [PATCH 11/14] Stop spewing all PC-FX ROMFONT glyphs to mednafen's TTY. --- mednafen/src/pcfx/debug.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mednafen/src/pcfx/debug.cpp b/mednafen/src/pcfx/debug.cpp index 11e1e9e..cf64efd 100755 --- a/mednafen/src/pcfx/debug.cpp +++ b/mednafen/src/pcfx/debug.cpp @@ -455,14 +455,16 @@ static void CPUHandler(const v810_timestamp_t timestamp, uint32 PC) const uint16 sc = PCFX_V810.GetPR(6) & 0xFFFF; const char* s = PCFXDBG_ShiftJIS_to_UTF8(sc); PCFXDBG_DoLog("ROMFONT", "0x%08x->0xFFF0000C, PR7=0x%08x=%s, PR6=0x%04x = %s", lastPC, pr7, (pr7 > 5) ? "?" : font_sizes[pr7], sc, s); +#if 0 for(const char* tmp = s; *tmp; tmp++) { const char c = *tmp; - if(c != 0x1B) + if(c < 0 || c >= 0x20) putchar(c); } fflush(stdout); +#endif } else if(PC == 0xFFF00008) DoSyscallLog(); From 390e89b7a549b0d01b84e4f3a785f9f060f63491 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sat, 17 Feb 2024 13:05:25 -0500 Subject: [PATCH 12/14] Change ADPCM LengthCount to 17-bits, but keep debugger at 16-bits. --- mednafen/src/pce/pcecd.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mednafen/src/pce/pcecd.cpp b/mednafen/src/pce/pcecd.cpp index ba36f25..5388531 100644 --- a/mednafen/src/pce/pcecd.cpp +++ b/mednafen/src/pce/pcecd.cpp @@ -131,7 +131,7 @@ typedef struct uint16 Addr; uint16 ReadAddr; uint16 WriteAddr; - uint16 LengthCount; + uint32 LengthCount; bool HalfReached; bool EndReached; @@ -277,7 +277,7 @@ uint32 PCECD_GetRegister(const unsigned int id, char *special, const uint32 spec break; case CD_GSREG_ADPCM_LENGTH: - value = ADPCM.LengthCount; + value = (ADPCM.LengthCount & 0x10000) ? 0xFFFF : ADPCM.LengthCount; break; case CD_GSREG_ADPCM_PLAYNIBBLE: @@ -1183,7 +1183,7 @@ static INLINE void ADPCM_Run(const int32 clocks, const int32 timestamp) if(ADPCM.WritePending <= 0) { ADPCM.HalfReached = (ADPCM.LengthCount < 32768); - if(!(ADPCM.LastCmd & 0x10) && ADPCM.LengthCount < 0xFFFF) + if(!(ADPCM.LastCmd & 0x10) && ADPCM.LengthCount < 0x1FFFF) ADPCM.LengthCount++; ADPCM.RAM[ADPCM.WriteAddr++] = ADPCM.WritePendingValue; From ad2195a9e76236112be1c8bc2c7f8fefc0f71972 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sat, 17 Feb 2024 13:08:35 -0500 Subject: [PATCH 13/14] Add code to handle PC Engine's SCSI "abort" sequence. --- mednafen/src/cdrom/scsicd.cpp | 47 ++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/mednafen/src/cdrom/scsicd.cpp b/mednafen/src/cdrom/scsicd.cpp index 2978b8d..e962cb8 100644 --- a/mednafen/src/cdrom/scsicd.cpp +++ b/mednafen/src/cdrom/scsicd.cpp @@ -2042,6 +2042,8 @@ static void DoREADBase(uint32 sa, uint32 sc) if(SectorCount) { Cur_CDIF->HintReadSector(sa); //, sa + sc); + cd.data_transfer_done = false; + ChangePhase(PHASE_DATA_IN); } else { @@ -3016,6 +3018,13 @@ uint32 SCSICD_Run(scsicd_timestamp_t system_timestamp) else switch(CurrentPhase) { case PHASE_COMMAND: + if((WhichSystem == SCSICD_PCE) && SEL_signal) + { + cd.command_buffer_pos = 0; + ChangePhase(PHASE_COMMAND); + break; + } + if(REQ_signal && ACK_signal) // Data bus is valid nowww { //printf("Command Phase Byte I->T: %02x, %d\n", cd_bus.DB, cd.command_buffer_pos); @@ -3025,7 +3034,15 @@ uint32 SCSICD_Run(scsicd_timestamp_t system_timestamp) if(!REQ_signal && !ACK_signal && cd.command_buffer_pos) // Received at least one byte, what should we do? { - if(cd.command_buffer_pos == RequiredCDBLen[cd.command_buffer[0] >> 4]) + if(cd.command_buffer[0] == 0xFF) + { + if(SCSILog) + SCSILog("SCSI", "Got Command $FF"); + + cd.command_buffer_pos = 0; + SendStatusAndMessage(STATUS_GOOD, 0x00); + } + else if(cd.command_buffer_pos == RequiredCDBLen[cd.command_buffer[0] >> 4]) { const SCSICH *cmd_info_ptr; @@ -3148,10 +3165,14 @@ uint32 SCSICD_Run(scsicd_timestamp_t system_timestamp) //if(cd_bus.DB == 0x6) // ABORT message! if(1) { + if(SCSILog) + SCSILog("SCSI", "SCSICD Abort Received(DB=0x%02x)", cd_bus.DB); + //printf("[SCSICD] Abort Received(DB=0x%02x)\n", cd_bus.DB); din->Flush(); cd.data_out_pos = cd.data_out_want = 0; + SectorCount = 0; CDReadTimer = 0; cdda.CDDAStatus = CDDASTATUS_STOPPED; ChangePhase(PHASE_BUS_FREE); @@ -3163,6 +3184,14 @@ uint32 SCSICD_Run(scsicd_timestamp_t system_timestamp) case PHASE_STATUS: + if((WhichSystem == SCSICD_PCE) && SEL_signal) + { + cd.status_sent = true; + cd.message_sent = true; + ChangePhase(PHASE_COMMAND); + break; + } + if(REQ_signal && ACK_signal) { SetREQ(false); @@ -3180,6 +3209,14 @@ uint32 SCSICD_Run(scsicd_timestamp_t system_timestamp) break; case PHASE_DATA_IN: + if((WhichSystem == SCSICD_PCE) && SEL_signal) + { + SectorCount = 0; + din->Flush(); + cd.data_transfer_done = true; + SetREQ(false); + } + if(!REQ_signal && !ACK_signal) { //puts("REQ and ACK false"); @@ -3200,6 +3237,7 @@ uint32 SCSICD_Run(scsicd_timestamp_t system_timestamp) SetREQ(true); } } + if(REQ_signal && ACK_signal) { //puts("REQ and ACK true"); @@ -3208,6 +3246,13 @@ uint32 SCSICD_Run(scsicd_timestamp_t system_timestamp) break; case PHASE_MESSAGE_IN: + if((WhichSystem == SCSICD_PCE) && SEL_signal) + { + cd.message_sent = false; + ChangePhase(PHASE_COMMAND); + break; + } + if(REQ_signal && ACK_signal) { SetREQ(false); From 6cf95ade194d16dc4abeb84c6b5cb66dc3ebc982 Mon Sep 17 00:00:00 2001 From: John Brandwood Date: Sat, 17 Feb 2024 13:16:57 -0500 Subject: [PATCH 14/14] Change PC Engine CD speed to 150KB/s. Implement missed-sector and sequential-read delays that keep PCE Sherlock Holmes happy. Fix PC-FX hang after SCSI-abort that was introduced the last time I tried to do this! --- mednafen/src/cdrom/scsicd-pce-commands.inc | 3 +- mednafen/src/cdrom/scsicd.cpp | 148 +++++++++++++-------- mednafen/src/cdrom/seektime_pce.cpp | 14 +- mednafen/src/cdrom/seektime_pce.h | 2 +- mednafen/src/pce/pce.cpp | 3 +- mednafen/src/pce/pcecd.cpp | 2 +- 6 files changed, 102 insertions(+), 70 deletions(-) diff --git a/mednafen/src/cdrom/scsicd-pce-commands.inc b/mednafen/src/cdrom/scsicd-pce-commands.inc index c049243..b7be8ca 100644 --- a/mednafen/src/cdrom/scsicd-pce-commands.inc +++ b/mednafen/src/cdrom/scsicd-pce-commands.inc @@ -48,7 +48,7 @@ static void DoNEC_PCE_SAPSP(const uint8 *cdb) read_sec = read_sec_start = new_read_sec_start; read_sec_end = toc.tracks[100].lba; - seekms = get_pce_cd_seek_ms(head_pos, read_sec, CD_DATA_TRANSFER_RATE); + seekms = get_pce_cd_seek_ms(head_pos, read_sec); //printf("From sec %6.6X to %6.6X (SAPSP), ms = %.2f\n", head_pos, read_sec, seekms); CDDASeekTimer = (uint64)(System_Clock * seekms / 1000); CDAudioDelay = (uint64)(System_Clock * 260 / 1000); @@ -263,6 +263,7 @@ static void DoNEC_PCE_GETDIRINFO(const uint8 *cdb) data_in[1] = U8_to_BCD(s); data_in[2] = U8_to_BCD(f); data_in[3] = toc.tracks[track].control; + data_in_size = 4; } break; diff --git a/mednafen/src/cdrom/scsicd.cpp b/mednafen/src/cdrom/scsicd.cpp index e962cb8..7e981ba 100644 --- a/mednafen/src/cdrom/scsicd.cpp +++ b/mednafen/src/cdrom/scsicd.cpp @@ -214,6 +214,7 @@ static int32 CDAudioDelay; // not added into savestates static uint32 SectorAddr; static uint32 SectorCount; static uint32 SectorIndex; +static uint32 PrevHeadAddress; static uint32 PrevSectorCount; static bool AllowThrottling = false; static bool Throttle120KBps = false; @@ -267,6 +268,7 @@ static void VirtualReset(void) din->Flush(); CDReadTimer = 0; + Throttle120KBps = false; head_pos = 0; CDDASeekTimer = 0; @@ -277,7 +279,7 @@ static void VirtualReset(void) pce_lastsapsp_timestamp = monotonic_timestamp; - PrevSectorCount = SectorAddr = SectorCount = SectorIndex = 0; + PrevHeadAddress = PrevSectorCount = SectorAddr = SectorCount = SectorIndex = 0; read_sec_start = read_sec = 0; read_sec_end = ~0; @@ -1982,17 +1984,13 @@ static void DoREADBase(uint32 sa, uint32 sc) return; } - if(SCSILog) + if(WhichSystem == SCSICD_PCE) { - int Track = toc.FindTrackByLBA(sa); - uint32 Offset = sa - toc.tracks[Track].lba; //Cur_CDIF->GetTrackStartPositionLBA(Track); - SCSILog("SCSI", "%sRead: start=0x%08x(track=%d, offs=0x%08x), cnt=0x%08x", (SectorAddr == sa) ? "Sequential" : "", sa, Track, Offset, sc); - } + int32 lastread_ms = (((int64) CDReadTimer * 1000) / System_Clock); - if (WhichSystem == SCSICD_PCE) - { - seekms = get_pce_cd_seek_ms(head_pos, sa, CD_DATA_TRANSFER_RATE); + seekms = get_pce_cd_seek_ms(head_pos, sa); //printf("From sec %6.6X to %6.6X (dat), ms = %.2f\n", head_pos, sa, seekms); + //printf("lastread_ms is %d\n", lastread_ms); // Sherlock Holmes Consulting Detective videos start with an 8 sector read // of ADPCM data, followed by sequential reads of 252 sectors. @@ -2005,36 +2003,76 @@ static void DoREADBase(uint32 sa, uint32 sc) // // That is *really* hard to emulate accurately, so instead the code limits // the data rate to 120KB/s by adding a delay every 6 sectors. + if(Throttle120KBps && sa != SectorAddr) + { + if(SCSILog) + SCSILog("SCSI", "Sherlock Holmes 120KB/s throttling deactivated"); + Throttle120KBps = false; + } - if (Throttle120KBps) + // If we're already throttling to 120KB/s, then do NOT change CDReadTimer + // when a new read is started, just use the old value from the last read. + if(!Throttle120KBps) { - if (sa == SectorAddr && sc == 252) - CDReadTimer += 0; // Streaming time is updated in SCSICD_Run! - else + // Detect Sherlock Holmes's video playback read pattern ... + // Read 6-sector video data at movie start LBA + // Read 8-sector ADPCM data at movie start LBA-8 + // Read 252-sector video data at movie start LBA + if(AllowThrottling && sc == 252 && PrevSectorCount == 8 && sa == SectorAddr && sa == (PrevHeadAddress - 6)) { - CDReadTimer = (uint64)(System_Clock * seekms / 1000); if(SCSILog) - SCSILog("SCSI", "SCSICD 120KB/s throttling deactivated"); - Throttle120KBps = false; + SCSILog("SCSI", "Sherlock Holmes 120KB/s throttling activated"); + Throttle120KBps = true; + CDReadTimer = ((uint64) System_Clock * seekms) / 1000; } - } - else - { - CDReadTimer = (uint64)(System_Clock * seekms / 1000); - if (AllowThrottling && PrevSectorCount == 8 && sa == SectorAddr && sc == 252) + else if((sa == SectorAddr) && (lastread_ms > -110) && (lastread_ms < -55)) { + // This is a nasty game-specific-hack to tune sequential read commands so + // that Sherlock Holmes's video does not de-sync while trying to simulate + // the FIFO-not-empty delays that the playback relies upon. + // + // The interaction between these two delays are complex, and also seem to + // to depend upon things like the emulated VDC write timings. + // + // Using the "AllowThrottling" flag is a much more honest, better looking, + // and less-likely-to-break-in-the-future solution to Sherlock's videos! if(SCSILog) - SCSILog("SCSI", "SCSICD 120KB/s throttling activated"); - Throttle120KBps = true; - CDReadTimer -= (uint64)(6 * System_Clock / 60); + SCSILog("SCSI", "QuickSequentialRead: start=0x%08x, cnt=0x%08x, previous=%dms", sa, sc, lastread_ms); + +// // This seems more accurate if considering the disc's rotation, but it does +// // not work in practice. +// // It seems that our seek timings are too fast at their fastest, and too slow at their slowest. +// CDReadTimer += ((uint64) System_Clock * seekms) / 1000; + + // So use a fixed 300ms-since-the-previous-read timing instead, which is what + // makes Sherlock's movies happy. This is 22.5 sectors of time so there seems + // to be some delays going on in the controller that we don't understand. + CDReadTimer -= ((uint64) 1 * 2048 * System_Clock) / CD_DATA_TRANSFER_RATE; + CDReadTimer += ((uint64) 300 * System_Clock) / 1000; + } + else + { + // If non-sequential or it's just been a while since the last read. + CDReadTimer = ((uint64) System_Clock * seekms) / 1000; } } } else { - CDReadTimer = (uint64)(1 * 2048 * System_Clock / CD_DATA_TRANSFER_RATE); + // If this is not SCSICD_PCE (i.e. a PC-FX). + CDReadTimer = ((uint64) 1 * 2048 * System_Clock) / CD_DATA_TRANSFER_RATE; } + if(SCSILog) + { + int Track = toc.FindTrackByLBA(sa); + uint32 Offset = sa - toc.tracks[Track].lba; //Cur_CDIF->GetTrackStartPositionLBA(Track); + SCSILog("SCSI", "%sRead: start=0x%08x(track=%d, offs=0x%08x), cnt=0x%08x, timer=%dms", (SectorAddr == sa) ? "Sequential" : "", sa, Track, Offset, sc, (int) (((int64) CDReadTimer * 1000) / System_Clock)); + } + + PrevHeadAddress = SectorAddr; + PrevSectorCount = sc; + SectorAddr = sa; SectorCount = sc; SectorIndex = 0; @@ -2050,7 +2088,6 @@ static void DoREADBase(uint32 sa, uint32 sc) CDReadTimer = 0; SendStatusAndMessage(STATUS_GOOD, 0x00); } - PrevSectorCount = SectorCount; cdda.CDDAStatus = CDDASTATUS_STOPPED; } @@ -2861,13 +2898,15 @@ static INLINE void RunCDDA(uint32 system_timestamp, int32 run_time) static INLINE void RunCDRead(uint32 system_timestamp, int32 run_time) { - // Allow CDReadTimer to go -ve 0.5s to track the CD-ROM's sector timing - // for mutliple reads asynchronous to the console's CPU. - if(CDReadTimer > (int32) - (System_Clock / 2)) + // Allow CDReadTimer to go -ve 1s to track the CD-ROM's sector timing + // for multiple reads asynchronous to the console's CPU. + if(CDReadTimer > (int32) - System_Clock) { - int32 OldCDReadTimer = CDReadTimer; CDReadTimer -= run_time; + // If Throttle120KBps, then reading the next sector can occur when CDReadTimer + // is -ve, but normally the FIFO-not-empty condition will push CDReadTimer +ve + // again as soon as it goes -ve. if(SectorCount && CDReadTimer <= 0) { if(din->CanWrite() < ((WhichSystem == SCSICD_PCFX) ? 2352 : 2048)) // +96 if we find out the PC-FX can read subchannel data along with raw data too. ;) @@ -2876,24 +2915,28 @@ static INLINE void RunCDRead(uint32 system_timestamp, int32 run_time) // everything *except* the PCE version of Sherlock Holmes, where it happens all // of the time, and the game seems to rely on it for throttling the read rate. // - // It is almost certain that both this method of determining when the condition - // occurs, and what the delay is that it causes, are totally incorrect! - - if (OldCDReadTimer > 0 && SectorCount != 0) + // N.B. This also happens a lot on the PC-FX, because video streaming begins by + // sending a READ for the entire movie length, then it just pauses reading when + // its buffer memory is full, and continues reading later on to refill it. + if(WhichSystem == SCSICD_PCE) { - if (SCSILog) - SCSILog("SCSI", "SCSICD FIFO not empty when CDReadTime expired, SectorAddr 0x%08x, SectorIndex %d", SectorAddr, SectorIndex); - } + if(!Throttle120KBps) + { + if(SCSILog) + SCSILog("SCSI", "SCSICD FIFO not empty when CDReadTime expired, SectorAddr 0x%08x", SectorAddr); - // Throttled CD-ROM reading accumulates CDReadTimer further down in the code! - if (!Throttle120KBps) + // Add a fixed 250ms to the delay, since this is what makes Sherlock's movies happy. + // This is 18.75 sectors of time, more than a single rotation of the CD, which means + // that something is going on in the controller that we don't understand. + CDReadTimer += ((uint64) 250 * System_Clock) / 1000; + } + } + else { - if (CD_DATA_TRANSFER_RATE == 153600) - // A value which seems plausible for real hardware. - CDReadTimer += (uint64) 16 * 2048 * System_Clock / CD_DATA_TRANSFER_RATE; - else - // A value which makes absolutely no sense. - CDReadTimer += (uint64) 1 * 2048 * System_Clock / CD_DATA_TRANSFER_RATE; + // A value which makes absolutely no sense, but the PC-FX needs something when it pauses reading a video stream. + // + // N.B. A test with Team Innocent shows that a more-realistic delay works fine. + CDReadTimer += ((uint64) 1 * 2048 * System_Clock) / CD_DATA_TRANSFER_RATE; } } else @@ -2915,13 +2958,13 @@ static INLINE void RunCDRead(uint32 system_timestamp, int32 run_time) { CommandCCError(SENSEKEY_ILLEGAL_REQUEST, NSE_END_OF_VOLUME); } - else if(SectorCount && !Cur_CDIF->ReadRawSector(tmp_read_buf, SectorAddr)) //, SectorAddr + SectorCount)) + else if(!Cur_CDIF->ReadRawSector(tmp_read_buf, SectorAddr)) //, SectorAddr + SectorCount)) { cd.data_transfer_done = false; CommandCCError(SENSEKEY_ILLEGAL_REQUEST); } - else if(SectorCount && ValidateRawDataSector(tmp_read_buf, SectorAddr)) + else if(ValidateRawDataSector(tmp_read_buf, SectorAddr)) { head_pos = SectorAddr; @@ -2937,21 +2980,21 @@ static INLINE void RunCDRead(uint32 system_timestamp, int32 run_time) CDIRQCallback(SCSICD_IRQ_DATA_TRANSFER_READY); SectorAddr++; - SectorIndex++; SectorCount--; if(CurrentPhase != PHASE_DATA_IN) ChangePhase(PHASE_DATA_IN); - CDReadTimer += (uint64) 1 * 2048 * System_Clock / CD_DATA_TRANSFER_RATE; + CDReadTimer += ((uint64) 1 * 2048 * System_Clock) / CD_DATA_TRANSFER_RATE; - if (Throttle120KBps && (SectorIndex % 6) == 0) + if(Throttle120KBps && (++SectorIndex == 6)) { // For every 6 sectors at 75 sectors/s, add a 1.5 sector delay to // provide an overall 60 sectors/s = 120KB/s. // This is simpler than simulating the CD-ROM drive's read-buffer // behavior on underruns, and it gives smoother streaming results. - CDReadTimer += (uint64) (3 * 2048 / 2) * System_Clock / CD_DATA_TRANSFER_RATE; + CDReadTimer += ((uint64) 3 * 2048 / 2 * System_Clock) / CD_DATA_TRANSFER_RATE; + SectorIndex = 0; } cd.data_transfer_done = (SectorCount == 0); @@ -3318,12 +3361,11 @@ void SCSICD_Init(int type, int cdda_time_div, int32* left_hrbuf, int32* right_hr if(type == SCSICD_PCFX) { din = new SimpleFIFO(65536); //4096); - AllowThrottling = false; } else { din = new SimpleFIFO(2048); //8192); //1024); /2048); - AllowThrottling = (MDFN_GetSettingB("pce.cdspeed") && MDFN_GetSettingB("pce.cdthrottle")); + AllowThrottling = MDFN_GetSettingB("pce.cdthrottle"); } WhichSystem = type; diff --git a/mednafen/src/cdrom/seektime_pce.cpp b/mednafen/src/cdrom/seektime_pce.cpp index 337da07..afcede5 100644 --- a/mednafen/src/cdrom/seektime_pce.cpp +++ b/mednafen/src/cdrom/seektime_pce.cpp @@ -57,7 +57,7 @@ static int find_sector_group(int sector_num) return group_index; } -float get_pce_cd_seek_ms(int start_sector, int target_sector, unsigned transfer_rate) +float get_pce_cd_seek_ms(int start_sector, int target_sector) { int start_index; int target_index; @@ -93,17 +93,7 @@ float get_pce_cd_seek_ms(int start_sector, int target_sector, unsigned transfer_ // Now, we use the algorithm to determine how long to wait if (abs(target_sector - start_sector) <= 3) { - if (transfer_rate == 153600) - { - // A value which closely matches real hardware. - milliseconds = (6 * 1000 / 60) + (float)(sector_list[target_index].rotation_ms * 0.75); - } - else - { - // An insanely-short value needed for Mednafen's traditional - // method of getting Sherlock Holmes video streaming to work. - milliseconds = (2 * 1000 / 60); - } + milliseconds = (6 * 1000 / 60) + (float)(sector_list[target_index].rotation_ms * 0.75); } else if (abs(target_sector - start_sector) < 7) { diff --git a/mednafen/src/cdrom/seektime_pce.h b/mednafen/src/cdrom/seektime_pce.h index 72bb759..cd242d0 100644 --- a/mednafen/src/cdrom/seektime_pce.h +++ b/mednafen/src/cdrom/seektime_pce.h @@ -8,5 +8,5 @@ ============================================================================ */ -extern float get_pce_cd_seek_ms(int start_sector, int target_sector, unsigned transfer_rate); +extern float get_pce_cd_seek_ms(int start_sector, int target_sector); diff --git a/mednafen/src/pce/pce.cpp b/mednafen/src/pce/pce.cpp index 5521fb8..7751d21 100644 --- a/mednafen/src/pce/pce.cpp +++ b/mednafen/src/pce/pce.cpp @@ -1125,8 +1125,7 @@ static const MDFNSetting PCESettings[] = { "pce.vramsize", MDFNSF_EMU_STATE | MDFNSF_UNTRUSTED_SAFE | MDFNSF_SUPPRESS_DOC, gettext_noop("Size of emulated VRAM per VDC in 16-bit words. DO NOT CHANGE THIS UNLESS YOU KNOW WTF YOU ARE DOING."), NULL, MDFNST_UINT, "32768", "32768", "65536" }, - { "pce.cdspeed", MDFNSF_NOFLAGS, gettext_noop("Emulate full CD-ROM transfer rate."), gettext_noop("Disable to use Mednafen's traditional reduced transfer rate and other hacks needed to get the Sherlock Holmes videos to play correctly."), MDFNST_BOOL, "0" }, - { "pce.cdthrottle", MDFNSF_NOFLAGS, gettext_noop("Enable CD throttling to 120KB/s when needed."), gettext_noop("When emulating the full CD-ROM transfer rate, this can be enabled to detect and throttle the Sherlock Holmes video playback to stop the audio and video going out of sync."), MDFNST_BOOL, "0" }, + { "pce.cdthrottle", MDFNSF_NOFLAGS, gettext_noop("Enable Sherlock Holmes best-quality video playback."), gettext_noop("This can be enabled to detect and throttle the Sherlock Holmes video playback to 120KB/s."), MDFNST_BOOL, "0" }, { NULL } }; diff --git a/mednafen/src/pce/pcecd.cpp b/mednafen/src/pce/pcecd.cpp index 5388531..7bbb176 100644 --- a/mednafen/src/pce/pcecd.cpp +++ b/mednafen/src/pce/pcecd.cpp @@ -455,7 +455,7 @@ void PCECD_Init(const PCECD_Settings *settings, void (*irqcb)(bool), double mast ADPCMBuf = adbuf; - SCSICD_Init(SCSICD_PCE, 3, hrbuf_l, hrbuf_r, MDFN_GetSettingB("pce.cdspeed") ? 153600 : 126000, master_clock, CDIRQ, StuffSubchannel); + SCSICD_Init(SCSICD_PCE, 3, hrbuf_l, hrbuf_r, 153600, master_clock, CDIRQ, StuffSubchannel); ADPCM.RAM = new uint8[0x10000];