mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-02-17 01:45:41 +00:00
Added handling of drive board (if attached)
This commit is contained in:
parent
07b94f6c32
commit
d7ee278f69
|
@ -356,8 +356,12 @@ UINT8 CModel3::ReadInputs(unsigned reg)
|
||||||
return data;
|
return data;
|
||||||
|
|
||||||
case 0x0C: // game-specific inputs
|
case 0x0C: // game-specific inputs
|
||||||
|
|
||||||
data = 0xFF;
|
data = 0xFF;
|
||||||
|
|
||||||
|
if (DriveBoard.IsAttached())
|
||||||
|
data = DriveBoard.Read();
|
||||||
|
|
||||||
if ((Game->inputFlags&GAME_INPUT_JOYSTICK2))
|
if ((Game->inputFlags&GAME_INPUT_JOYSTICK2))
|
||||||
{
|
{
|
||||||
data &= ~(Inputs->up[1]->value<<5); // P2 Up
|
data &= ~(Inputs->up[1]->value<<5); // P2 Up
|
||||||
|
@ -461,6 +465,12 @@ void CModel3::WriteInputs(unsigned reg, UINT8 data)
|
||||||
EEPROM.Write((data>>6)&1,(data>>7)&1,(data>>5)&1);
|
EEPROM.Write((data>>6)&1,(data>>7)&1,(data>>5)&1);
|
||||||
inputBank = data;
|
inputBank = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x10: // Drive board
|
||||||
|
if (DriveBoard.IsAttached())
|
||||||
|
DriveBoard.Write(data);
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x24: // Serial FIFO 1
|
case 0x24: // Serial FIFO 1
|
||||||
switch (data) // Command
|
switch (data) // Command
|
||||||
{
|
{
|
||||||
|
@ -1831,6 +1841,8 @@ void CModel3::SaveState(CBlockFile *SaveState)
|
||||||
TileGen.SaveState(SaveState);
|
TileGen.SaveState(SaveState);
|
||||||
GPU.SaveState(SaveState);
|
GPU.SaveState(SaveState);
|
||||||
SoundBoard.SaveState(SaveState); // also saves DSB state
|
SoundBoard.SaveState(SaveState); // also saves DSB state
|
||||||
|
if (DriveBoard.IsAttached())
|
||||||
|
DriveBoard.SaveState(SaveState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::LoadState(CBlockFile *SaveState)
|
void CModel3::LoadState(CBlockFile *SaveState)
|
||||||
|
@ -1864,6 +1876,8 @@ void CModel3::LoadState(CBlockFile *SaveState)
|
||||||
IRQ.LoadState(SaveState);
|
IRQ.LoadState(SaveState);
|
||||||
ppc_load_state(SaveState);
|
ppc_load_state(SaveState);
|
||||||
SoundBoard.LoadState(SaveState);
|
SoundBoard.LoadState(SaveState);
|
||||||
|
if (DriveBoard.IsAttached())
|
||||||
|
DriveBoard.LoadState(SaveState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::SaveNVRAM(CBlockFile *NVRAM)
|
void CModel3::SaveNVRAM(CBlockFile *NVRAM)
|
||||||
|
@ -1906,11 +1920,7 @@ void CModel3::RunFrame(void)
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Wake sound board and drive board threads so they can process a frame
|
// Wake sound board and drive board threads so they can process a frame
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
if (!sndBrdThreadSync->Post() || DriveBoard.IsAttached() && !drvBrdThreadSync->Post())
|
||||||
if (!sndBrdThreadSync->Post() || !drvBrdThreadSync->Post())
|
|
||||||
#else
|
|
||||||
if (!sndBrdThreadSync->Post())
|
|
||||||
#endif
|
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// At the same time, process a single frame for main board (PPC) in this thread
|
// At the same time, process a single frame for main board (PPC) in this thread
|
||||||
|
@ -1921,19 +1931,13 @@ void CModel3::RunFrame(void)
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Wait for sound board and drive board threads to finish their work (if they haven't done so already)
|
// Wait for sound board and drive board threads to finish their work (if they haven't done so already)
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
while (!sndBrdThreadDone || DriveBoard.IsAttached() && !drvBrdThreadDone)
|
||||||
while (!sndBrdThreadDone || !drvBrdThreadDone)
|
|
||||||
#else
|
|
||||||
while (!sndBrdThreadDone)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if (!notifySync->Wait(notifyLock))
|
if (!notifySync->Wait(notifyLock))
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
}
|
}
|
||||||
sndBrdThreadDone = false;
|
sndBrdThreadDone = false;
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
drvBrdThreadDone = false;
|
drvBrdThreadDone = false;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Leave notify wait critical section
|
// Leave notify wait critical section
|
||||||
if (!notifyLock->Unlock())
|
if (!notifyLock->Unlock())
|
||||||
|
@ -1944,9 +1948,8 @@ void CModel3::RunFrame(void)
|
||||||
// If not multi-threaded, then just process a single frame for main board, sound board and drive board in turn in this thread
|
// If not multi-threaded, then just process a single frame for main board, sound board and drive board in turn in this thread
|
||||||
RunMainBoardFrame();
|
RunMainBoardFrame();
|
||||||
SoundBoard.RunFrame();
|
SoundBoard.RunFrame();
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
if (DriveBoard.IsAttached())
|
||||||
DriveBoard.RunFrame();
|
DriveBoard.RunFrame();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1965,11 +1968,12 @@ bool CModel3::StartThreads()
|
||||||
sndBrdThreadSync = CThread::CreateSemaphore(1);
|
sndBrdThreadSync = CThread::CreateSemaphore(1);
|
||||||
if (sndBrdThreadSync == NULL)
|
if (sndBrdThreadSync == NULL)
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
if (DriveBoard.IsAttached())
|
||||||
drvBrdThreadSync = CThread::CreateSemaphore(1);
|
{
|
||||||
if (drvBrdThreadSync == NULL)
|
drvBrdThreadSync = CThread::CreateSemaphore(1);
|
||||||
goto ThreadError;
|
if (drvBrdThreadSync == NULL)
|
||||||
#endif
|
goto ThreadError;
|
||||||
|
}
|
||||||
notifyLock = CThread::CreateMutex();
|
notifyLock = CThread::CreateMutex();
|
||||||
if (notifyLock == NULL)
|
if (notifyLock == NULL)
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
@ -1982,12 +1986,13 @@ bool CModel3::StartThreads()
|
||||||
if (sndBrdThread == NULL)
|
if (sndBrdThread == NULL)
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
// Create drive board thread, if drive board is attached
|
||||||
// Create drive board thread
|
if (DriveBoard.IsAttached())
|
||||||
drvBrdThread = CThread::CreateThread(StartDriveBoardThread, this);
|
{
|
||||||
if (drvBrdThread == NULL)
|
drvBrdThread = CThread::CreateThread(StartDriveBoardThread, this);
|
||||||
goto ThreadError;
|
if (drvBrdThread == NULL)
|
||||||
#endif
|
goto ThreadError;
|
||||||
|
}
|
||||||
|
|
||||||
startedThreads = true;
|
startedThreads = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -2017,13 +2022,11 @@ void CModel3::DeleteThreadObjects()
|
||||||
delete sndBrdThread;
|
delete sndBrdThread;
|
||||||
sndBrdThread = NULL;
|
sndBrdThread = NULL;
|
||||||
}
|
}
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
if (drvBrdThread != NULL)
|
if (drvBrdThread != NULL)
|
||||||
{
|
{
|
||||||
delete drvBrdThread;
|
delete drvBrdThread;
|
||||||
drvBrdThread = NULL;
|
drvBrdThread = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Delete synchronization objects
|
// Delete synchronization objects
|
||||||
if (sndBrdThreadSync != NULL)
|
if (sndBrdThreadSync != NULL)
|
||||||
|
@ -2031,13 +2034,11 @@ void CModel3::DeleteThreadObjects()
|
||||||
delete sndBrdThreadSync;
|
delete sndBrdThreadSync;
|
||||||
sndBrdThreadSync = NULL;
|
sndBrdThreadSync = NULL;
|
||||||
}
|
}
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
if (drvBrdThreadSync != NULL)
|
if (drvBrdThreadSync != NULL)
|
||||||
{
|
{
|
||||||
delete drvBrdThreadSync;
|
delete drvBrdThreadSync;
|
||||||
drvBrdThreadSync = NULL;
|
drvBrdThreadSync = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
if (notifyLock != NULL)
|
if (notifyLock != NULL)
|
||||||
{
|
{
|
||||||
delete notifyLock;
|
delete notifyLock;
|
||||||
|
@ -2058,7 +2059,6 @@ int CModel3::StartSoundBoardThread(void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
int CModel3::StartDriveBoardThread(void *data)
|
int CModel3::StartDriveBoardThread(void *data)
|
||||||
{
|
{
|
||||||
// Call drive board thread method on CModel3
|
// Call drive board thread method on CModel3
|
||||||
|
@ -2066,7 +2066,6 @@ int CModel3::StartDriveBoardThread(void *data)
|
||||||
model3->RunDriveBoardThread();
|
model3->RunDriveBoardThread();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void CModel3::RunSoundBoardThread()
|
void CModel3::RunSoundBoardThread()
|
||||||
{
|
{
|
||||||
|
@ -2098,7 +2097,6 @@ ThreadError:
|
||||||
g_Config.multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
void CModel3::RunDriveBoardThread()
|
void CModel3::RunDriveBoardThread()
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -2108,7 +2106,7 @@ void CModel3::RunDriveBoardThread()
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Process a single frame for drive board
|
// Process a single frame for drive board
|
||||||
//DriveBoard.RunFrame();
|
DriveBoard.RunFrame();
|
||||||
|
|
||||||
// Enter notify critical section
|
// Enter notify critical section
|
||||||
if (!notifyLock->Lock())
|
if (!notifyLock->Lock())
|
||||||
|
@ -2128,8 +2126,6 @@ ThreadError:
|
||||||
ErrorLog("Threading error in drive board thread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in drive board thread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
g_Config.multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void CModel3::RunMainBoardFrame(void)
|
void CModel3::RunMainBoardFrame(void)
|
||||||
{
|
{
|
||||||
// Run the PowerPC for a frame
|
// Run the PowerPC for a frame
|
||||||
|
@ -2141,7 +2137,7 @@ void CModel3::RunMainBoardFrame(void)
|
||||||
GPU.BeginFrame();
|
GPU.BeginFrame();
|
||||||
GPU.RenderFrame();
|
GPU.RenderFrame();
|
||||||
IRQ.Assert(0x02);
|
IRQ.Assert(0x02);
|
||||||
ppc_execute(10000); // TO-DO: Vblank probably needs to be longer. Maybe that's why some games run too fast/slow
|
ppc_execute(10000); // TO-DO: Vblank probably needs to be longer. Maybe that's why some games run too fast/slow
|
||||||
//printf("PC=%08X LR=%08X\n", ppc_get_pc(), ppc_get_lr());
|
//printf("PC=%08X LR=%08X\n", ppc_get_pc(), ppc_get_lr());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2216,9 +2212,9 @@ void CModel3::Reset(void)
|
||||||
TileGen.Reset();
|
TileGen.Reset();
|
||||||
GPU.Reset();
|
GPU.Reset();
|
||||||
SoundBoard.Reset();
|
SoundBoard.Reset();
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
DriveBoard.Reset();
|
if (DriveBoard.IsAttached())
|
||||||
#endif
|
DriveBoard.Reset();
|
||||||
|
|
||||||
DebugLog("Model 3 reset\n");
|
DebugLog("Model 3 reset\n");
|
||||||
}
|
}
|
||||||
|
@ -2643,6 +2639,9 @@ void CModel3::AttachInputs(CInputs *InputsPtr)
|
||||||
{
|
{
|
||||||
Inputs = InputsPtr;
|
Inputs = InputsPtr;
|
||||||
|
|
||||||
|
if (DriveBoard.IsAttached())
|
||||||
|
DriveBoard.AttachInputs(InputsPtr, Game->inputFlags);
|
||||||
|
|
||||||
DebugLog("Model 3 attached inputs\n");
|
DebugLog("Model 3 attached inputs\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2666,6 +2665,7 @@ BOOL CModel3::Init(void)
|
||||||
mpegROM = &memoryPool[OFFSET_DSBMPEGROM];
|
mpegROM = &memoryPool[OFFSET_DSBMPEGROM];
|
||||||
backupRAM = &memoryPool[OFFSET_BACKUPRAM];
|
backupRAM = &memoryPool[OFFSET_BACKUPRAM];
|
||||||
securityRAM = &memoryPool[OFFSET_SECURITYRAM];
|
securityRAM = &memoryPool[OFFSET_SECURITYRAM];
|
||||||
|
driveROM = NULL; // TODO - need to read drive board ROM, but not complain if it is not available
|
||||||
SetCROMBank(0xFF);
|
SetCROMBank(0xFF);
|
||||||
|
|
||||||
// Initialize other devices (PowerPC and DSB initialized after ROMs loaded)
|
// Initialize other devices (PowerPC and DSB initialized after ROMs loaded)
|
||||||
|
@ -2681,10 +2681,8 @@ BOOL CModel3::Init(void)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
if (OKAY != SoundBoard.Init(soundROM,sampleROM))
|
if (OKAY != SoundBoard.Init(soundROM,sampleROM))
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
if (OKAY != DriveBoard.Init(driveROM))
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
return FAIL;
|
||||||
DriveBoard.Init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PCIBridge.AttachPCIBus(&PCIBus);
|
PCIBridge.AttachPCIBus(&PCIBus);
|
||||||
PCIBus.AttachDevice(13,&GPU);
|
PCIBus.AttachDevice(13,&GPU);
|
||||||
|
@ -2720,17 +2718,11 @@ CModel3::CModel3(void)
|
||||||
|
|
||||||
startedThreads = false;
|
startedThreads = false;
|
||||||
sndBrdThread = NULL;
|
sndBrdThread = NULL;
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
drvBrdThread = NULL;
|
drvBrdThread = NULL;
|
||||||
#endif
|
|
||||||
sndBrdThreadDone = false;
|
sndBrdThreadDone = false;
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
drvBrdThreadDone = false;
|
drvBrdThreadDone = false;
|
||||||
#endif
|
|
||||||
sndBrdThreadSync = NULL;
|
sndBrdThreadSync = NULL;
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
drvBrdThreadSync = NULL;
|
drvBrdThreadSync = NULL;
|
||||||
#endif
|
|
||||||
notifyLock = NULL;
|
notifyLock = NULL;
|
||||||
notifySync = NULL;
|
notifySync = NULL;
|
||||||
|
|
||||||
|
|
|
@ -308,14 +308,10 @@ private:
|
||||||
void DeleteThreadObjects(); // Deletes all threads and synchronization objects
|
void DeleteThreadObjects(); // Deletes all threads and synchronization objects
|
||||||
|
|
||||||
static int StartSoundBoardThread(void *data); // Callback to start sound board thread
|
static int StartSoundBoardThread(void *data); // Callback to start sound board thread
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
static int StartDriveBoardThread(void *data); // Callback to start drive board thread
|
static int StartDriveBoardThread(void *data); // Callback to start drive board thread
|
||||||
#endif
|
|
||||||
|
|
||||||
void RunSoundBoardThread(); // Runs sound board thread
|
void RunSoundBoardThread(); // Runs sound board thread
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
void RunDriveBoardThread(); // Runs drive board thread
|
void RunDriveBoardThread(); // Runs drive board thread
|
||||||
#endif
|
|
||||||
|
|
||||||
// Game and hardware information
|
// Game and hardware information
|
||||||
const struct GameInfo *Game;
|
const struct GameInfo *Game;
|
||||||
|
@ -343,6 +339,7 @@ private:
|
||||||
UINT8 *mpegROM; // 8 MB DSB MPEG ROM
|
UINT8 *mpegROM; // 8 MB DSB MPEG ROM
|
||||||
UINT8 *backupRAM; // 128 KB Backup RAM (battery backed)
|
UINT8 *backupRAM; // 128 KB Backup RAM (battery backed)
|
||||||
UINT8 *securityRAM; // 128 KB Security Board RAM
|
UINT8 *securityRAM; // 128 KB Security Board RAM
|
||||||
|
UINT8 *driveROM; // 32 KB drive board ROM (Z80 program) (optional)
|
||||||
|
|
||||||
// Banked CROM
|
// Banked CROM
|
||||||
UINT8 *cromBank; // currently mapped in CROM bank
|
UINT8 *cromBank; // currently mapped in CROM bank
|
||||||
|
@ -357,19 +354,13 @@ private:
|
||||||
// Multiple threading
|
// Multiple threading
|
||||||
bool startedThreads; // True if threads have been created and started
|
bool startedThreads; // True if threads have been created and started
|
||||||
CThread *sndBrdThread; // Sound board thread
|
CThread *sndBrdThread; // Sound board thread
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
CThread *drvBrdThread; // Drive board thread
|
CThread *drvBrdThread; // Drive board thread
|
||||||
#endif
|
|
||||||
bool sndBrdThreadDone; // Flag to indicate sound board thread has finished processing for current frame
|
bool sndBrdThreadDone; // Flag to indicate sound board thread has finished processing for current frame
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
bool drvBrdThreadDone; // Flag to indicate drive board thread has finished processing for current frame
|
bool drvBrdThreadDone; // Flag to indicate drive board thread has finished processing for current frame
|
||||||
#endif
|
|
||||||
|
|
||||||
// Thread synchronization objects
|
// Thread synchronization objects
|
||||||
CSemaphore *sndBrdThreadSync;
|
CSemaphore *sndBrdThreadSync;
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
CSemaphore *drvBrdThreadSync;
|
CSemaphore *drvBrdThreadSync;
|
||||||
#endif
|
|
||||||
CMutex *notifyLock;
|
CMutex *notifyLock;
|
||||||
CCondVar *notifySync;
|
CCondVar *notifySync;
|
||||||
|
|
||||||
|
@ -384,9 +375,7 @@ private:
|
||||||
CReal3D GPU; // Real3D graphics hardware
|
CReal3D GPU; // Real3D graphics hardware
|
||||||
CSoundBoard SoundBoard; // Sound board
|
CSoundBoard SoundBoard; // Sound board
|
||||||
CDSB *DSB; // Digital Sound Board (type determined dynamically at load time)
|
CDSB *DSB; // Digital Sound Board (type determined dynamically at load time)
|
||||||
#ifdef SUPERMODEL_DRIVEBOARD
|
|
||||||
CDriveBoard DriveBoard; // Drive board
|
CDriveBoard DriveBoard; // Drive board
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue