mirror of
https://github.com/MiSTer-devel/PSX_MiSTer.git
synced 2026-04-19 03:04:52 +00:00
Merge pull request #341 from Kuba-J/main
CD: Add optional backward seek hack (Dave Mirra, Thrasher), fix INT1 handling (Parodius, Crime Crackers, Yakyū ’95), fix DMA read from empty sector buffer (MiruMiru demo), Fix PAUSE timing
This commit is contained in:
8
PSX.sv
8
PSX.sv
@@ -345,7 +345,7 @@ wire reset_or = RESET | buttons[1] | status[0] | bios_download | exe_download |
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
// 01234567890123456789012345678901 23456789012345678901234567890123 45678901234567890123456789012345
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV
|
||||
// XXXX XXXXXX XXXXXX XXXXX XX XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// XXXX XXXXXX XXXXXX XXXXX XX XX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
`include "build_id.v"
|
||||
parameter CONF_STR = {
|
||||
@@ -423,9 +423,10 @@ parameter CONF_STR = {
|
||||
"P2O[21],CD Fast Seek,Off,On(U);",
|
||||
"P2O[77:75],CD Speed,Original,Forced 1X(U),Forced 2X(U),Hack 4X(U),Hack 6X(U),Hack 8X(U);",
|
||||
"P2O[78],Limit Max CD Speed,Off,On(U);",
|
||||
"P2O[93],Backward Seek Hack,Off,On(U);",
|
||||
"P2O[85],RAM(Homebrew),2 MByte,8 MByte(U);",
|
||||
"P2O[90],GPU Slowdown,Off,On(U);",
|
||||
"P2O[92],Old GPU,Off,On;",
|
||||
"P2O[92],Old GPU(CXD8514Q),Off,On;",
|
||||
"P2-;",
|
||||
"P2O[28],FPS Overlay,Off,On;",
|
||||
"P2O[74],Error Overlay,Off,On;",
|
||||
@@ -941,7 +942,7 @@ always @(posedge clk_1x) begin
|
||||
if (!padMode[1]) psx_info <= 8'd18;
|
||||
end else if (cdinfo_download_1 && ~cdinfo_download) begin
|
||||
// warning for every unsafe option
|
||||
if (status[89] || status[80:79] > 0 || status[72] || status[15] || status[21] || status[77:75] > 0 || status[78] || status[85]) begin
|
||||
if (status[89] || status[80:79] > 0 || status[72] || status[15] || status[21] || status[77:75] > 0 || status[78] || status[85] || status[93]) begin
|
||||
psx_info_req <= 1;
|
||||
psx_info <= 8'd24;
|
||||
end else if (status[40:39] == 2'b00) begin
|
||||
@@ -1109,6 +1110,7 @@ psx
|
||||
.REPRODUCIBLESPUDMA(status[43]),
|
||||
.WIDESCREEN(status[54:53]),
|
||||
.oldGPU(status[92]),
|
||||
.backwardSeekHack(status[93]),
|
||||
|
||||
// RAM/BIOS interface
|
||||
.biosregion(biosregion),
|
||||
|
||||
@@ -19,6 +19,7 @@ SDRAM of any size is required.
|
||||
* 8 Mbyte mode(from dev units, mostly for homebrew)
|
||||
* Inputs: DualShock, Digital, Analog, Mouse, NeGcon, Wheel, Justifier and Guncon support.
|
||||
* Native Input support through SNAC
|
||||
* Old GPU (CXD8514Q)
|
||||
|
||||
## Bios
|
||||
Rename your playstation bios file (e.g. `scph-1001.bin`/`ps-22a.bin` ) and place it in the `./games/PSX/` folder.
|
||||
@@ -47,7 +48,7 @@ You need to save them either manually in the OSD or turn on autosave. Saving or
|
||||
|
||||
## Multiple Disc Games
|
||||
|
||||
To swap discs while the game is running, you will need have all of the disc files for the game placed in the same folder. Then when loading a new disc for most games you will need to toggle the Lid Open/Close option to tell the game you have opened the lid and closed it. Example folder structure of a multi disc game:
|
||||
To swap discs while the game is running, all disc files for the game must be placed in the same folder. When a disc change is required, the core will automatically simulate opening and closing the disc lid. Example folder structure of a multi-disc game:
|
||||
|
||||
```
|
||||
/media/fat/games/PSX/Final Fantasy VII (USA)/Final Fantasy VII (USA) (Disc 1).chd
|
||||
@@ -107,6 +108,11 @@ The higher speed rates are more unstable and require proper storage to be usable
|
||||
Will hold back any new CD data until the game has processed the last data.
|
||||
Mostly useful to prevent CD data overrun when using higher speed modes, leading to overall faster loading times due to less read retries.
|
||||
|
||||
- Backward Seek Hack:
|
||||
Fixes long stutters in Dave Mirra and Thrasher games related to backward CD seeks.
|
||||
The drive continues reading normally, while sectors ahead of the seek target are temporarily hidden from the CPU until the correct position is reached.
|
||||
Generally safe, but may affect a small number of sensitive titles (e.g. some Army Men games).
|
||||
|
||||
- RAM:
|
||||
8 Mbyte option from development consoles. Only use for homebrew that requires it, otherwise there is a high chance of crashing games.
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ entity cd_top is
|
||||
pauseOnCDSlow : in std_logic;
|
||||
region : in std_logic_vector(1 downto 0);
|
||||
region_out : out std_logic_vector(1 downto 0);
|
||||
|
||||
backwardSeekHack : in std_logic;
|
||||
|
||||
pauseCD : out std_logic := '0';
|
||||
Pause_idle_cd : out std_logic := '0';
|
||||
@@ -714,19 +716,24 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (ackRead = '1' or ackRead_data = '1') then
|
||||
if (CDROM_IRQFLAG = "00001") then -- irq for sector still pending, sector missed
|
||||
-- will be handled when next sector is fetched from cpu interface
|
||||
elsif (CDROM_IRQFLAG /= "00000") then -- store sector done if current irq is something else, so CPU will be notified later
|
||||
pendingDriveIRQ <= "00001";
|
||||
pendingDriveResponse <= internalStatus;
|
||||
if (ackRead = '1' or ackRead_data = '1') then
|
||||
if (CDROM_IRQFLAG = "00011") then
|
||||
-- INT3 active: do not overwrite it with INT1
|
||||
-- queue INT1 for later delivery
|
||||
if (pendingDriveIRQ = "00000") then
|
||||
pendingDriveIRQ <= "00001";
|
||||
pendingDriveResponse <= internalStatus;
|
||||
end if;
|
||||
else
|
||||
if (CDROM_IRQFLAG /= "00000" and CDROM_IRQFLAG /= "00001") then
|
||||
pendingDriveIRQ <= CDROM_IRQFLAG;
|
||||
end if;
|
||||
CDROM_IRQFLAG <= "00001";
|
||||
if (CDROM_IRQENA(0) = '1') then
|
||||
irqOut <= '1';
|
||||
end if;
|
||||
ackRead_valid <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (ackPendingIRQNext = '1') then
|
||||
@@ -1105,11 +1112,11 @@ begin
|
||||
workCommand <= nextCmd;
|
||||
cmdResetXa <= '1';
|
||||
if (driveState = DRIVE_READING or driveState = DRIVE_PLAYING) then
|
||||
-- todo: should this be swapped between single speed and double speed? DuckStation has double speed longer and psx spx doc has single speed being longer
|
||||
-- Matches psx spx doc and DuckStation
|
||||
if (modeReg(7) = '1') then
|
||||
workDelay <= 2157295 + driveDelay; -- value from psx spx doc
|
||||
else
|
||||
workDelay <= 1066874 + driveDelay; -- value from psx spx doc
|
||||
else
|
||||
workDelay <= 2157295 + driveDelay; -- value from psx spx doc
|
||||
end if;
|
||||
end if;
|
||||
if (driveState = DRIVE_SEEKLOGICAL or driveState = DRIVE_SEEKPHYSICAL or driveState = DRIVE_SEEKIMPLICIT) then
|
||||
@@ -1915,9 +1922,13 @@ begin
|
||||
ackDriveEnd <= '1';
|
||||
else
|
||||
skipreading := '0';
|
||||
if (setLocActive = '1' and (currentLBA - seekLBA) >= 2) then
|
||||
skipreading := '1';
|
||||
end if;
|
||||
-- optional fix for Dave Mirra / Trasher
|
||||
if (backwardSeekHack = '1') then
|
||||
if (setLocActive = '1' and (currentLBA - seekLBA) >= 2) then
|
||||
skipreading := '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if (isAudio = '1') then
|
||||
if (currentTrackBCD = x"00") then -- auto find track number from subheader
|
||||
currentTrackBCD <= nextSubdata(1);
|
||||
@@ -2817,19 +2828,23 @@ begin
|
||||
case (copyState) is
|
||||
|
||||
when COPY_IDLE =>
|
||||
if (copyData = '1' and ce = '1') then
|
||||
if (copyData = '1' and ce = '1' and
|
||||
sectorBufferSizes(to_integer(readSectorPointer)) /= 0) then
|
||||
|
||||
copyState <= COPY_FIRST;
|
||||
copyCount <= 0;
|
||||
copyReadAddr <= 0;
|
||||
copyByteCnt <= 0;
|
||||
copySectorPointer <= readSectorPointer;
|
||||
sectorBufferSizes(to_integer(readSectorPointer)) <= 0;
|
||||
if (sectorBufferSizes(to_integer(readSectorPointer)) = 0) then
|
||||
copySize <= RAW_SECTOR_OUTPUT_SIZE / 4;
|
||||
else
|
||||
copySize <= sectorBufferSizes(to_integer(readSectorPointer));
|
||||
end if;
|
||||
-- read size before clearing buffer size
|
||||
if (sectorBufferSizes(to_integer(readSectorPointer)) = 0) then
|
||||
copySize <= RAW_SECTOR_OUTPUT_SIZE / 4;
|
||||
else
|
||||
copySize <= sectorBufferSizes(to_integer(readSectorPointer));
|
||||
end if;
|
||||
-- clear buffer size after size was latched
|
||||
sectorBufferSizes(to_integer(readSectorPointer)) <= 0;
|
||||
end if;
|
||||
|
||||
when COPY_FIRST =>
|
||||
copyState <= COPY_DATA;
|
||||
|
||||
@@ -66,6 +66,7 @@ entity psx_mister is
|
||||
REPRODUCIBLESPUDMA : in std_logic;
|
||||
WIDESCREEN : in std_logic_vector(1 downto 0);
|
||||
oldGPU : in std_logic;
|
||||
backwardSeekHack : in std_logic;
|
||||
-- RAM/BIOS interface
|
||||
biosregion : in std_logic_vector(1 downto 0);
|
||||
ram_refresh : out std_logic;
|
||||
@@ -359,6 +360,7 @@ begin
|
||||
REPRODUCIBLESPUDMA => REPRODUCIBLESPUDMA,
|
||||
WIDESCREEN => WIDESCREEN,
|
||||
oldGPU => oldGPU,
|
||||
backwardSeekHack => backwardSeekHack,
|
||||
-- RAM/BIOS interface
|
||||
biosregion => biosregion,
|
||||
ram_refresh => ram_refresh,
|
||||
|
||||
@@ -70,6 +70,7 @@ entity psx_top is
|
||||
REPRODUCIBLESPUDMA : in std_logic;
|
||||
WIDESCREEN : in std_logic_vector(1 downto 0);
|
||||
oldGPU : in std_logic;
|
||||
backwardSeekHack : in std_logic;
|
||||
-- RAM/BIOS interface
|
||||
biosregion : in std_logic_vector(1 downto 0);
|
||||
ram_refresh : out std_logic;
|
||||
@@ -1404,6 +1405,8 @@ begin
|
||||
LIDopen => LIDopen,
|
||||
region => region,
|
||||
region_out => region_out,
|
||||
|
||||
backwardSeekHack => backwardSeekHack,
|
||||
|
||||
pauseCD => pauseCD,
|
||||
Pause_idle_cd => Pause_idle_cd,
|
||||
|
||||
Reference in New Issue
Block a user