- PCI bridge can be specified in Games.xml for games that use a different version than expected based on stepping. No more hard-coded exceptions.

- Real3D PCI ID can be specified in Games.xml for exceptions that require it.
- Real3D status bit timing specified in Games.xml for exceptions that require it.
This commit is contained in:
SpinDizzy 2019-01-13 16:00:37 +00:00
parent d8f736e7a8
commit b0813ef7a0
9 changed files with 132 additions and 65 deletions

View file

@ -19,6 +19,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.0</stepping> <stepping>1.0</stepping>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="fishing" /> <input type="fishing" />
@ -86,6 +87,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.0</stepping> <stepping>1.0</stepping>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="fishing" /> <input type="fishing" />
@ -110,6 +112,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.0</stepping> <stepping>1.0</stepping>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="fishing" /> <input type="fishing" />
@ -141,6 +144,7 @@
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.1</stepping> <stepping>2.1</stepping>
<mpeg_board>DSB2</mpeg_board> <mpeg_board>DSB2</mpeg_board>
<real3d_status_bit_set_percent_of_frame>24</real3d_status_bit_set_percent_of_frame>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="vehicle" /> <input type="vehicle" />
@ -320,6 +324,7 @@
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.1</stepping> <stepping>2.1</stepping>
<mpeg_board>DSB2</mpeg_board> <mpeg_board>DSB2</mpeg_board>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="vehicle" /> <input type="vehicle" />
@ -392,6 +397,7 @@
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.1</stepping> <stepping>2.1</stepping>
<mpeg_board>DSB2</mpeg_board> <mpeg_board>DSB2</mpeg_board>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="vehicle" /> <input type="vehicle" />
@ -426,6 +432,7 @@
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.1</stepping> <stepping>2.1</stepping>
<mpeg_board>DSB2</mpeg_board> <mpeg_board>DSB2</mpeg_board>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="vehicle" /> <input type="vehicle" />
@ -460,6 +467,7 @@
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.1</stepping> <stepping>2.1</stepping>
<mpeg_board>DSB2</mpeg_board> <mpeg_board>DSB2</mpeg_board>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="vehicle" /> <input type="vehicle" />
@ -686,6 +694,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.0</stepping> <stepping>2.0</stepping>
<real3d_status_bit_set_percent_of_frame>24</real3d_status_bit_set_percent_of_frame>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="joystick1" /> <input type="joystick1" />
@ -763,6 +772,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.0</stepping> <stepping>2.0</stepping>
<real3d_status_bit_set_percent_of_frame>24</real3d_status_bit_set_percent_of_frame>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="joystick1" /> <input type="joystick1" />
@ -891,6 +901,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.1</stepping> <stepping>2.1</stepping>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="analog_gun1" /> <input type="analog_gun1" />
@ -1150,6 +1161,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.1</stepping> <stepping>2.1</stepping>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="magtruck" /> <input type="magtruck" />
@ -1508,6 +1520,7 @@
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.5</stepping> <stepping>1.5</stepping>
<mpeg_board>DSB1</mpeg_board> <mpeg_board>DSB1</mpeg_board>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="vehicle" /> <input type="vehicle" />
@ -2078,10 +2091,14 @@
<year>1998</year> <year>1998</year>
</identity> </identity>
<hardware> <hardware>
<!--
To get this running at full speed, set PowerPC frequency to 100 MHz on
command line or in INI file.
-->
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.0</stepping> <stepping>2.0</stepping>
<!-- Spindizzi notes : Add mpeg soundboard -->
<mpeg_board>DSB2</mpeg_board> <mpeg_board>DSB2</mpeg_board>
<real3d_status_bit_set_percent_of_frame>48</real3d_status_bit_set_percent_of_frame>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="vehicle" /> <input type="vehicle" />
@ -2544,6 +2561,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.0</stepping> <stepping>2.0</stepping>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="twin_joysticks" /> <input type="twin_joysticks" />
@ -2619,6 +2637,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.0</stepping> <stepping>2.0</stepping>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="twin_joysticks" /> <input type="twin_joysticks" />
@ -2645,6 +2664,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.0</stepping> <stepping>2.0</stepping>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="twin_joysticks" /> <input type="twin_joysticks" />
@ -2671,6 +2691,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>2.0</stepping> <stepping>2.0</stepping>
<real3d_pci_id>0x16C311DB</real3d_pci_id>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="twin_joysticks" /> <input type="twin_joysticks" />
@ -2771,6 +2792,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.5</stepping> <stepping>1.5</stepping>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="joystick1" /> <input type="joystick1" />
@ -2798,6 +2820,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.5</stepping> <stepping>1.5</stepping>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="joystick1" /> <input type="joystick1" />
@ -2912,6 +2935,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.5</stepping> <stepping>1.5</stepping>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="joystick1" /> <input type="joystick1" />
@ -3041,6 +3065,7 @@
<hardware> <hardware>
<platform>Sega Model 3</platform> <platform>Sega Model 3</platform>
<stepping>1.5</stepping> <stepping>1.5</stepping>
<pci_bridge>MPC106</pci_bridge>
<inputs> <inputs>
<input type="common" /> <input type="common" />
<input type="joystick1" /> <input type="joystick1" />

View file

@ -14,6 +14,9 @@ struct Game
unsigned year = 0; unsigned year = 0;
std::string stepping; std::string stepping;
std::string mpeg_board; std::string mpeg_board;
std::string pci_bridge; // overrides default PCI bridge type for stepping (empty string for default)
uint32_t real3d_pci_id = 0; // overrides default Real3D PCI ID for stepping (0 for default)
float real3d_status_bit_set_percent_of_frame = 0; // overrides default status bit timing (0 for default)
uint32_t encryption_key = 0; uint32_t encryption_key = 0;
enum Inputs enum Inputs
{ {

View file

@ -197,6 +197,9 @@ static void PopulateGameInfo(Game *game, const Util::Config::Node &game_node)
game->year = game_node["identity/year"].ValueAsDefault<unsigned>(0); game->year = game_node["identity/year"].ValueAsDefault<unsigned>(0);
game->stepping = game_node["hardware/stepping"].ValueAsDefault<std::string>(""); game->stepping = game_node["hardware/stepping"].ValueAsDefault<std::string>("");
game->mpeg_board = game_node["hardware/mpeg_board"].ValueAsDefault<std::string>(""); game->mpeg_board = game_node["hardware/mpeg_board"].ValueAsDefault<std::string>("");
game->pci_bridge = game_node["hardware/pci_bridge"].ValueAsDefault<std::string>("");
game->real3d_pci_id = game_node["hardware/real3d_pci_id"].ValueAsDefault<uint32_t>(0);
game->real3d_status_bit_set_percent_of_frame = game_node["hardware/real3d_status_bit_set_percent_of_frame"].ValueAsDefault<float>(0);
game->encryption_key = game_node["hardware/encryption_key"].ValueAsDefault<uint32_t>(0); game->encryption_key = game_node["hardware/encryption_key"].ValueAsDefault<uint32_t>(0);
std::map<std::string, uint32_t> input_flags std::map<std::string, uint32_t> input_flags
{ {

View file

@ -1,7 +1,7 @@
/** /**
** Supermodel ** Supermodel
** A Sega Model 3 Arcade Emulator. ** A Sega Model 3 Arcade Emulator.
** Copyright 2011 Bart Trzynadlowski, Nik Henson ** Copyright 2011-2019 Bart Trzynadlowski, Nik Henson, Ian Curtis
** **
** This file is part of Supermodel. ** This file is part of Supermodel.
** **
@ -319,6 +319,16 @@ void CMPC10x::SetModel(int modelNum)
DebugLog("MPC10x set to MPC%X\n", model); DebugLog("MPC10x set to MPC%X\n", model);
} }
/*
* CMPC10x::GetModel():
*
* Returns the model number.
*/
int CMPC10x::GetModel() const
{
return model;
}
/* /*
* CMPC10x::Init(): * CMPC10x::Init():
* *

View file

@ -146,6 +146,14 @@ public:
* to MPC105 if unrecognized. * to MPC105 if unrecognized.
*/ */
void SetModel(int modelNum); void SetModel(int modelNum);
/*
* GetModel(void):
*
* Returns:
* The PCI bridge model number, either 0x105 or 0x106.
*/
int GetModel() const;
/* /*
* Init(void): * Init(void):

View file

@ -1,7 +1,7 @@
/** /**
** Supermodel ** Supermodel
** A Sega Model 3 Arcade Emulator. ** A Sega Model 3 Arcade Emulator.
** Copyright 2011-2016 Bart Trzynadlowski, Nik Henson ** Copyright 2011-2019 Bart Trzynadlowski, Nik Henson, Ian Curtis
** **
** This file is part of Supermodel. ** This file is part of Supermodel.
** **
@ -553,12 +553,20 @@ UINT8 CModel3::ReadInputs(unsigned reg)
adc[1] = (UINT8)Inputs->analogGunX[1]->value; adc[1] = (UINT8)Inputs->analogGunX[1]->value;
adc[3] = (UINT8)Inputs->analogGunY[1]->value; adc[3] = (UINT8)Inputs->analogGunY[1]->value;
if (m_game.name == "lostwsga" || m_game.name == "lostwsgo") { // to do, not a string compare /*
// Unclear why this is necessary or how to cleanly fix it, so I'm
// disabling it but leaving it here for future reference. The proper fix is
// probably to allow users to define inverted controls for this game only,
// which means the input system must support loading per-game config (not
// all analog_gun games require axis inversion to be playable).
if (m_game.name == "lostwsga" || m_game.name == "lostwsgo")
{ // to do, not a string compare
adc[0] = (UINT8)Inputs->analogGunX[0]->value; // order is different for some reason in lost world adc[0] = (UINT8)Inputs->analogGunX[0]->value; // order is different for some reason in lost world
adc[1] = 255 - (UINT8)Inputs->analogGunY[0]->value; // why are values inverted? is this the wrong place to fix this adc[1] = 255 - (UINT8)Inputs->analogGunY[0]->value; // why are values inverted? is this the wrong place to fix this
adc[2] = (UINT8)Inputs->analogGunX[1]->value; adc[2] = (UINT8)Inputs->analogGunX[1]->value;
adc[3] = 255 - (UINT8)Inputs->analogGunY[1]->value; adc[3] = 255 - (UINT8)Inputs->analogGunY[1]->value;
} }
*/
} }
if ((m_game.inputs & Game::INPUT_SKI)) if ((m_game.inputs & Game::INPUT_SKI))
@ -2205,32 +2213,29 @@ void CModel3::RunMainBoardFrame(void)
unsigned vblCycles = (unsigned)((float) frameCycles * 2.5f/100.0f); // 2.5% vblank (ridiculously short and wrong but bigger values cause flicker in Daytona) unsigned vblCycles = (unsigned)((float) frameCycles * 2.5f/100.0f); // 2.5% vblank (ridiculously short and wrong but bigger values cause flicker in Daytona)
unsigned dispCycles = frameCycles - vblCycles; unsigned dispCycles = frameCycles - vblCycles;
// Scale PPC timer ratio according to speed at which the PowerPC is being emulated so that the observed running frequency of the PPC timer // For some reason, some Step 2.x games require completely different timings. The defaults can be overriden in the ROM set XML file.
// registers is more or less correct. This is needed to get the Virtua Striker 2 series of games running at the right speed (they are float real3DStatusBitSetAsPercentOfFrame = m_game.real3d_status_bit_set_percent_of_frame;
// too slow otherwise). Other games appear to not be affected by this ratio so much as their running speed depends more on the timing of if (real3DStatusBitSetAsPercentOfFrame <= 0)
// the Real3D status bit below. {
ppc_set_timer_ratio(ppc_get_bus_freq_multipler() * 2 * ppcCycles / ppc_get_cycles_per_sec()); if (m_game.stepping == "2.0" || m_game.stepping == "2.1")
real3DStatusBitSetAsPercentOfFrame = 9.12f;
else if (m_game.stepping == "1.5")
real3DStatusBitSetAsPercentOfFrame = 5.5f;
else
real3DStatusBitSetAsPercentOfFrame = 48.0f;
}
// Compute timing of the Real3D status bit. This value directly affects the speed at which all the games except Virtua Stiker 2 run. // Compute timing of the Real3D status bit. This value directly affects the speed at which all the games except Virtua Stiker 2 run.
// Currently it is not known exactly what this bit represents nor why such wildly varying values are needed for the different step models. // Currently it is not known exactly what this bit represents nor why such wildly varying values are needed for the different step models.
// The values below were arrived at by trial and error and clearly more investigation is required. If it turns out that the status bit is // The values below were arrived at by trial and error and clearly more investigation is required. If it turns out that the status bit is
// connected to the end of VBlank then the code below should be removed and the timing handled via GPU.VBlankEnd() instead. // connected to the end of VBlank then the code below should be removed and the timing handled via GPU.VBlankEnd() instead.
unsigned statusCycles; unsigned statusCycles = (unsigned) ((float) frameCycles * (real3DStatusBitSetAsPercentOfFrame * 1e-2f));
if (m_game.stepping == "2.0" || m_game.stepping == "2.1")
{ // Scale PPC timer ratio according to speed at which the PowerPC is being emulated so that the observed running frequency of the PPC timer
// For some reason, Fighting Vipers 2 and Daytona USA 2 require completely different timing to the rest of the step 2.x games // registers is more or less correct. This is needed to get the Virtua Striker 2 series of games running at the right speed (they are
if (m_game.name == "daytona2" || (m_game.stepping == "2.0" && (m_game.name == "fvipers2" || m_game.name == "fvipers2o"))) // too slow otherwise). Other games appear to not be affected by this ratio so much as their running speed depends more on the timing of
statusCycles = (unsigned)((float)frameCycles * 24.0f/100.0f); // the Real3D status bit below.
// Spindizzi notes : this little hack timing allow srally2x to run full speed (for test purpose only) ppc_set_timer_ratio(ppc_get_bus_freq_multipler() * 2 * ppcCycles / ppc_get_cycles_per_sec());
else if (m_game.name == "srally2x") // need ppc=100 also (edit ini or add option in command line)
statusCycles = (unsigned)((float)frameCycles * 48.0f / 100.0f);
else
statusCycles = (unsigned)((float)frameCycles * 9.12f/100.0f);
}
else if (m_game.stepping == "1.5")
statusCycles = (unsigned)((float)frameCycles * 5.5f/100.0f);
else
statusCycles = (unsigned)((float)frameCycles * 48.0f/100.0f);
// VBlank // VBlank
if (gpusReady) if (gpusReady)
@ -3089,44 +3094,46 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
Util::FlipEndian16(soundROM, 512*1024); Util::FlipEndian16(soundROM, 512*1024);
Util::FlipEndian16(sampleROM, 16*0x100000); Util::FlipEndian16(sampleROM, 16*0x100000);
// Initialize CPU // Configure CPU and PCI bridge
PPC_CONFIG ppc_config; PPC_CONFIG ppc_config;
if (game.stepping == "2.0" || game.stepping == "2.1") if (game.stepping == "2.0" || game.stepping == "2.1")
{ {
ppc_config.pvr = PPC_MODEL_603R; // 166 MHz ppc_config.pvr = PPC_MODEL_603R; // 166 MHz
ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ; ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ;
ppc_config.bus_frequency_multiplier = 0x25; // 2.5X multiplier ppc_config.bus_frequency_multiplier = 0x25; // 2.5X multiplier
PCIBridge.SetModel(0x106); // MPC106 PCIBridge.SetModel(0x106); // MPC106
} }
else if (game.stepping == "1.5") else if (game.stepping == "1.5")
{ {
ppc_config.pvr = PPC_MODEL_603E; // 100 MHz ppc_config.pvr = PPC_MODEL_603E; // 100 MHz
ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ; ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ;
ppc_config.bus_frequency_multiplier = 0x15; // 1.5X multiplier ppc_config.bus_frequency_multiplier = 0x15; // 1.5X multiplier
if (game.name == "scudplusa" PCIBridge.SetModel(0x105); // MPC105
|| game.name == "vs215" || game.name == "vs215o"
|| game.name == "vs29815" || game.name == "vs29915"
)
PCIBridge.SetModel(0x106); // some Step 1.x games use MPC106
else
PCIBridge.SetModel(0x105); // MPC105
} }
else if (game.stepping == "1.0") else if (game.stepping == "1.0")
{ {
ppc_config.pvr = PPC_MODEL_603R; // 66 MHz ppc_config.pvr = PPC_MODEL_603R; // 66 MHz
ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ; ppc_config.bus_frequency = BUS_FREQUENCY_66MHZ;
ppc_config.bus_frequency_multiplier = 0x10; // 1X multiplier ppc_config.bus_frequency_multiplier = 0x10; // 1X multiplier
if (game.name == "bass" || game.name == "bassdx" || game.name == "getbass") PCIBridge.SetModel(0x105); // MPC105
PCIBridge.SetModel(0x106); // some Step 1.x games use MPC106
else
PCIBridge.SetModel(0x105); // MPC105
} }
else else
{ {
ErrorLog("Cannot configure Model 3 because game uses unrecognized stepping (%s).", game.stepping.c_str()); ErrorLog("Cannot configure Model 3 because game uses unrecognized stepping (%s).", game.stepping.c_str());
return FAIL; return FAIL;
} }
if (!game.pci_bridge.empty())
{
if (game.pci_bridge == "MPC105")
PCIBridge.SetModel(0x105);
else if (game.pci_bridge == "MPC106")
PCIBridge.SetModel(0x106);
else
ErrorLog("Unknown PCI bridge specified in ROM set definition file (%s). Defaulting to MPC%X.", game.pci_bridge.c_str(), PCIBridge.GetModel());
}
// Initialize CPU
ppc_init(&ppc_config); ppc_init(&ppc_config);
ppc_attach_bus(this); ppc_attach_bus(this);
PPCFetchRegions[0].start = 0; PPCFetchRegions[0].start = 0;
@ -3141,18 +3148,13 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
ppc_set_fetch(PPCFetchRegions); ppc_set_fetch(PPCFetchRegions);
// Initialize Real3D // Initialize Real3D
int stepping = ((game.stepping[0] - '0') << 4) | (game.stepping[2] - '0'); int stepping = ((game.stepping[0] - '0') << 4) | (game.stepping[2] - '0');
// Some step 2+ games need the older PCI ID (obvious symptom: uint32_t real3DPCIID = game.real3d_pci_id;
// vbl is enabled briefly then disabled so the game hangs) if (0 == real3DPCIID)
bool step20_with_old_real3d; {
if (game.name == "von2" || game.name == "von2a" || game.name == "von254g" || game.name == "von2o" real3DPCIID = stepping >= 0x20 ? CReal3D::PCIID::Step2x : CReal3D::PCIID::Step1x;
|| game.name == "dirtdvls" || game.name == "dirtdvlsa" || game.name == "dirtdvlsj" || game.name == "dirtdvlsg" }
|| game.name == "magtruck" || game.name == "lamachin" GPU.SetStepping(stepping, real3DPCIID);
)
step20_with_old_real3d = true;
else
step20_with_old_real3d = false;
GPU.SetStepping(stepping, step20_with_old_real3d);
// MPEG board (if present) // MPEG board (if present)
if (rom_set.get_rom("mpeg_program").size) if (rom_set.get_rom("mpeg_program").size)

View file

@ -883,7 +883,7 @@ uint32_t CReal3D::GetASICIDCode(ASIC asic) const
return it == m_asicID.end() ? 0 : it->second; return it == m_asicID.end() ? 0 : it->second;
} }
void CReal3D::SetStepping(int stepping, bool step20_with_old_real3d) void CReal3D::SetStepping(int stepping, uint32_t pciIDValue)
{ {
step = stepping; step = stepping;
@ -894,12 +894,7 @@ void CReal3D::SetStepping(int stepping, bool step20_with_old_real3d)
} }
// Set PCI ID // Set PCI ID
// Some step 2+ games need the older PCI ID (obvious symptom: pciID = pciIDValue;
// vbl is enabled briefly then disabled so the game hangs)
if ((step < 0x20) || step20_with_old_real3d)
pciID = 0x16C311DB; // vendor 0x11DB = Sega
else
pciID = 0x178611DB;
// Pass to renderer // Pass to renderer
if (Render3D != NULL) if (Render3D != NULL)

View file

@ -59,6 +59,22 @@ struct QueuedUploadTextures
class CReal3D: public IPCIDevice class CReal3D: public IPCIDevice
{ {
public: public:
/*
* PCI IDs
*
* The CReal3D object must be configured with the desired ID. Some Step 2.x
* appear to defy this and expect the 1.x ID. The symptom of this is that
* VBL is enabled briefly then disabled. This should be investigated further.
* Perhaps a different ASIC's PCI ID is being read in these situations?
*
* The vendor ID code 0x11db is Sega's.
*/
enum PCIID: uint32_t
{
Step1x = 0x16C311DB, // Step 1.x
Step2x = 0x178611DB // Step 2.x
};
/* /*
* ASIC Names * ASIC Names
* *
@ -352,17 +368,22 @@ public:
uint32_t GetASICIDCode(ASIC asic) const; uint32_t GetASICIDCode(ASIC asic) const;
/* /*
* SetStepping(stepping): * SetStepping(stepping, pciIDValue):
* *
* Sets the Model 3 hardware stepping, which also determines the Real3D * Sets the Model 3 hardware stepping, which also determines the Real3D
* functionality. The default is Step 1.0. This should be called prior to * functionality. The default is Step 1.0. This should be called prior to
* any other emulation functions and after Init(). * any other emulation functions and after Init().
* *
* Parameters: * Parameters:
* stepping 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0, or * stepping 0x10 for Step 1.0, 0x15 for Step 1.5, 0x20 for Step 2.0, or
* 0x21 for Step 2.1. Anything else defaults to 1.0. * 0x21 for Step 2.1. Anything else defaults to 1.0.
* pciIDValue The PCI ID code to return. This should be one of the PCIID
* enum values otherwise games may fail to boot. Although the
* PCI ID depends on stepping, there are a few games that
* have to be explicitly configured with an older ID code,
* which is why this parameter is exposed.
*/ */
void SetStepping(int stepping, bool step20_with_old_real3d); void SetStepping(int stepping, uint32_t pciIDValue);
/* /*

View file

@ -1365,7 +1365,7 @@ static Util::Config::Node DefaultConfig()
static void Title(void) static void Title(void)
{ {
puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")"); puts("Supermodel: A Sega Model 3 Arcade Emulator (Version " SUPERMODEL_VERSION ")");
puts("Copyright 2011-2018 by Bart Trzynadlowski, Nik Henson, Ian Curtis,"); puts("Copyright 2011-2019 by Bart Trzynadlowski, Nik Henson, Ian Curtis,");
puts(" Harry Tuttle, and Spindizzi\n"); puts(" Harry Tuttle, and Spindizzi\n");
} }