Skip to content

Conversation

@gm-matthew
Copy link
Contributor

@gm-matthew gm-matthew commented Nov 10, 2025

When emulating Sega Model 2, 2A and 2C, if the TGP or TGPx4 DSP tries to read data from the input FIFO buffer but it is empty, the Model 2 driver will halt the DSP, improving emulation performance since the DSP is no longer running cycles while waiting for data.

This is not quite as simple for the SHARC DSP on Model 2B since it uses input flags to report the status of the FIFO buffers; it does not try to read the input FIFO buffer until it has confirmed that it is not empty by setting up an infinite loop that runs until flag #0 is clear.

Most Model 2B games set up a loop that repeatedly executes a NOP with the condition that flag #0 must be clear before exiting the loop, for example:

02013E  DO (0x0002013F) UNTIL NOT FLAG0_IN
02013F  NOP

Virtua Striker instead has an instruction that jumps to itself if flag #0 is set:

020119  IF FLAG0_IN, JUMP (0x00020119)

For both cases I have made it so that the emulated SHARC eats the remaining cycles in its timeslice if a flag is causing a loop, since the flag state cannot change until the i960 is run which can only happen after the SHARC has finished its timeslice. For the former case, it only eats the remaining cycles if the looping instruction is a NOP to ensure that there can be no difference in results compared to letting the remaining cycles run.

Improves performance in Sega Model 2B games
@mamehaze
Copy link
Contributor

mamehaze commented Nov 10, 2025

is it really safe to do this in the CPU core?

if a system is using a timer interrupt to wake the SHARC (as opposed to an external source) won't this cause problems with timing? (or does the SHARC not have that capability?)

@Hydreigon223
Copy link
Contributor

Has this been tested to a full extent with nwk-tr.cpp and hornet.cpp?

@gm-matthew
Copy link
Contributor Author

is it really safe to do this in the CPU core?

if a system is using a timer interrupt to wake the SHARC (as opposed to an external source) won't this cause problems with timing? (or does the SHARC not have that capability?)

The SHARC is not an interruptible device in MAME; once execute_run() is called it must complete its timeslice before any other events such as timer interrupts can occur. The exception is if an emulated CPU device itself triggers a machine-wide sync, which should not be possible in either of the cases where the SHARC stalls itself.

Has this been tested to a full extent with nwk-tr.cpp and hornet.cpp?

I have not yet tested NWK-TR or Hornet games; I shall do so and report if any problems occur.

@TheLostNinja
Copy link

I tested an artifact, and it seems to me that game speed became even faster than it actually should be (the funniest thing that some framedrops to the ~%80-%90 still left - in the Gunblade NY opening demo, for example).

@gm-matthew
Copy link
Contributor Author

I tested an artifact, and it seems to me that game speed became even faster than it actually should be (the funniest thing that some framedrops to the ~%80-%90 still left - in the Gunblade NY opening demo, for example).

That may be because MAME doesn't emulate wait states and so games are not as prone to slowdown as they would be on real hardware.

@gm-matthew
Copy link
Contributor Author

Has this been tested to a full extent with nwk-tr.cpp and hornet.cpp?

I have tested every single game in nwk-tr.cpp, hornet.cpp and also gticlub.cpp and none of them ever make the SHARC spin in a loop until a flag input is set/cleared, so they are unaffected by this commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants