mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-22 05:45:38 +00:00
- Added mutex for MIDI FIFO access to SCSP.cpp.
This commit is contained in:
parent
d200dff89e
commit
5bf4a6d52b
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** This file is part of Supermodel.
|
||||
**
|
||||
|
@ -500,7 +500,8 @@ bool CSoundBoard::Init(const UINT8 *soundROMPtr, const UINT8 *sampleROMPtr)
|
|||
// Initialize SCSPs
|
||||
SCSP_SetBuffers(audioL, audioR, 44100/60);
|
||||
SCSP_SetCB(SCSP68KRunCallback, SCSP68KIRQCallback);
|
||||
SCSP_Init(2);
|
||||
if (OKAY != SCSP_Init(2))
|
||||
return FAIL;
|
||||
SCSP_SetRAM(0, ram1);
|
||||
SCSP_SetRAM(1, ram2);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "Types.h"
|
||||
#include "CPU/Bus.h"
|
||||
#include "Model3/DSB.h"
|
||||
#include "OSD/Thread.h"
|
||||
|
||||
/*
|
||||
* CSoundBoardConfig:
|
||||
|
|
|
@ -1,10 +1,37 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** This file is part of Supermodel.
|
||||
**
|
||||
** Supermodel is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU General Public License as published by the Free
|
||||
** Software Foundation, either version 3 of the License, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
** more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License along
|
||||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
/*
|
||||
* Thread.cpp
|
||||
*
|
||||
* SDL-based implementation of threading primitives.
|
||||
*/
|
||||
|
||||
#include "Supermodel.h"
|
||||
|
||||
|
||||
#ifdef SUPERMODEL_OSX
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include <SDL/SDL_thread.h>
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_thread.h>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** This file is part of Supermodel.
|
||||
**
|
||||
** Supermodel is free software: you can redistribute it and/or modify it under
|
||||
** the terms of the GNU General Public License as published by the Free
|
||||
** Software Foundation, either version 3 of the License, or (at your option)
|
||||
** any later version.
|
||||
**
|
||||
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
|
||||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
** more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License along
|
||||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||
**/
|
||||
|
||||
/*
|
||||
* Thread.h
|
||||
*
|
||||
* Header file for threading primitives.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_THREADS_H
|
||||
#define INCLUDED_THREADS_H
|
||||
|
||||
|
@ -7,10 +34,10 @@ class CCondVar;
|
|||
|
||||
typedef int (*ThreadStart)(void *startParam);
|
||||
|
||||
/*
|
||||
* CThread
|
||||
*
|
||||
* Class that represents an O/S thread.
|
||||
/*
|
||||
* CThread
|
||||
*
|
||||
* Class that represents an O/S thread.
|
||||
*/
|
||||
class CThread
|
||||
{
|
||||
|
@ -122,7 +149,7 @@ public:
|
|||
};
|
||||
|
||||
/*
|
||||
* CSemaphore
|
||||
* CCondVar
|
||||
*
|
||||
* Class that represents a condition variable.
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
** Supermodel
|
||||
** A Sega Model 3 Arcade Emulator.
|
||||
** Copyright 2011 Bart Trzynadlowski
|
||||
** Copyright 2011 Bart Trzynadlowski, Nik Henson
|
||||
**
|
||||
** This file is part of Supermodel.
|
||||
**
|
||||
|
@ -116,6 +116,7 @@ unsigned int RevR,RevW;
|
|||
#define DWORD UINT32
|
||||
#endif
|
||||
|
||||
static CMutex *MIDILock; // for safe access to the MIDI FIFOs
|
||||
static int (*Run68kCB)(int cycles);
|
||||
static void (*Int68kCB)(int irq);
|
||||
static void (*RetIntCB)();
|
||||
|
@ -332,14 +333,31 @@ void CheckPendingIRQ()
|
|||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* MIDI FIFO critical section
|
||||
*
|
||||
* NOTE: I don't think a mutex is really needed here, so I've disabled
|
||||
* this critical section.
|
||||
*/
|
||||
//if (g_Config.multiThreaded)
|
||||
// MIDILock->Lock();
|
||||
|
||||
if(MidiW!=MidiR)
|
||||
{
|
||||
//if (g_Config.multiThreaded)
|
||||
// MIDILock->Unlock();
|
||||
|
||||
//SCSP.data[0x20/2]|=0x8; //Hold midi line while there are commands pending
|
||||
Int68kCB(IrqMidi);
|
||||
//printf("68K: MIDI IRQ\n");
|
||||
//ErrorLogMessage("Midi");
|
||||
return;
|
||||
}
|
||||
|
||||
//if (g_Config.multiThreaded)
|
||||
// MIDILock->Unlock();
|
||||
|
||||
if(!pend)
|
||||
return;
|
||||
if(pend&0x40)
|
||||
|
@ -535,7 +553,7 @@ void SCSP_StopSlot(_SLOT *slot,int keyoff)
|
|||
|
||||
#define log2(n) (log((float) n)/log((float) 2))
|
||||
|
||||
void SCSP_Init(int n)
|
||||
bool SCSP_Init(int n)
|
||||
{
|
||||
if(n==2)
|
||||
{
|
||||
|
@ -712,10 +730,30 @@ void SCSP_Init(int n)
|
|||
#endif
|
||||
|
||||
LFO_Init();
|
||||
buffertmpl = NULL;
|
||||
buffertmpr = NULL;
|
||||
buffertmpl=(signed int*) malloc(44100*sizeof(signed int));
|
||||
if (NULL == buffertmpl)
|
||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
||||
buffertmpr=(signed int*) malloc(44100*sizeof(signed int));
|
||||
if (NULL == buffertmpl)
|
||||
{
|
||||
free(buffertmpl);
|
||||
return ErrorLog("Insufficient memory for internal SCSP buffers.");
|
||||
}
|
||||
memset(buffertmpl,0,44100*sizeof(signed int));
|
||||
memset(buffertmpr,0,44100*sizeof(signed int));
|
||||
|
||||
// MIDI FIFO mutex
|
||||
MIDILock = CThread::CreateMutex();
|
||||
if (NULL == MIDILock)
|
||||
{
|
||||
free(buffertmpl);
|
||||
free(buffertmpr);
|
||||
return ErrorLog("Unable to create MIDI mutex!");
|
||||
}
|
||||
|
||||
return OKAY;
|
||||
}
|
||||
|
||||
void SCSP_SetRAM(int n,unsigned char *r)
|
||||
|
@ -887,6 +925,13 @@ void SCSP_UpdateRegR(int reg)
|
|||
{
|
||||
unsigned short v=SCSP->data[0x5/2];
|
||||
v&=0xff00;
|
||||
|
||||
/*
|
||||
* MIDI FIFO critical section!
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
v|=MidiStack[MidiR];
|
||||
//printf("read MIDI\n");
|
||||
if(MidiR!=MidiW)
|
||||
|
@ -894,11 +939,13 @@ void SCSP_UpdateRegR(int reg)
|
|||
++MidiR;
|
||||
MidiR&=MIDI_STACK_SIZE_MASK;
|
||||
//Int68kCB(IrqMidi);
|
||||
|
||||
}
|
||||
|
||||
MidiInFill--;
|
||||
SCSP->data[0x5/2]=v;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
|
@ -1870,46 +1917,100 @@ void SCSP_SetCB(int (*Run68k)(int cycles),void (*Int68k)(int irq))
|
|||
|
||||
void SCSP_MidiIn(BYTE val)
|
||||
{
|
||||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
//DebugLog("Midi Buffer push %02X",val);
|
||||
|
||||
MidiStack[MidiW++]=val;
|
||||
MidiW&=MIDI_STACK_SIZE_MASK;
|
||||
MidiInFill++;
|
||||
//Int68kCB(IrqMidi);
|
||||
// SCSP.data[0x20/2]|=0x8;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
}
|
||||
|
||||
void SCSP_MidiOutW(BYTE val)
|
||||
{
|
||||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
//printf("68K: MIDI out\n");
|
||||
//DebugLog("Midi Out Buffer push %02X",val);
|
||||
MidiStack[MidiOutW++]=val;
|
||||
MidiOutW&=7;
|
||||
++MidiOutFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
}
|
||||
|
||||
|
||||
unsigned char SCSP_MidiOutR()
|
||||
{
|
||||
unsigned char val;
|
||||
if(MidiOutR==MidiOutW)
|
||||
|
||||
if(MidiOutR==MidiOutW) // I don't think this needs to be a critical section...
|
||||
return 0xff;
|
||||
|
||||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
val=MidiStack[MidiOutR++];
|
||||
//DebugLog("Midi Out Buffer pop %02X",val);
|
||||
MidiOutR&=7;
|
||||
--MidiOutFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned char SCSP_MidiOutFill()
|
||||
{
|
||||
return MidiOutFill;
|
||||
unsigned char v;
|
||||
|
||||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
v = MidiOutFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned char SCSP_MidiInFill()
|
||||
{
|
||||
return MidiInFill;
|
||||
unsigned char v;
|
||||
|
||||
/*
|
||||
* MIDI FIFO critical section
|
||||
*/
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Lock();
|
||||
|
||||
v = MidiInFill;
|
||||
|
||||
if (g_Config.multiThreaded)
|
||||
MIDILock->Unlock();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void SCSP_RTECheck()
|
||||
|
@ -2218,4 +2319,8 @@ void SCSP_Deinit(void)
|
|||
#endif
|
||||
free(buffertmpl);
|
||||
free(buffertmpr);
|
||||
delete MIDILock;
|
||||
buffertmpl = NULL;
|
||||
buffertmpr = NULL;
|
||||
MIDILock = NULL;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,22 @@ UINT8 SCSP_MidiOutFill();
|
|||
UINT8 SCSP_MidiInFill();
|
||||
void SCSP_CpuRunScanline();
|
||||
UINT8 SCSP_MidiOutR();
|
||||
void SCSP_Init(int n);
|
||||
|
||||
/*
|
||||
* SCSP_Init(n):
|
||||
*
|
||||
* Initializes the SCSPs, allocates internal memory, and creates a mutex for
|
||||
* MIDI FIFO access. Call SCSP_SetCB() and SCSP_SetBuffers() before calling
|
||||
* this.
|
||||
*
|
||||
* Parameters:
|
||||
* n Number of SCSPs to create. Always use 2!
|
||||
*
|
||||
* Returns:
|
||||
* FAIL if an error occured (prints own error messages), OKAY otherwise.
|
||||
*/
|
||||
bool SCSP_Init(int n);
|
||||
|
||||
void SCSP_SetRAM(int n,UINT8 *r);
|
||||
void SCSP_RTECheck();
|
||||
int SCSP_IRQCB(int);
|
||||
|
|
Loading…
Reference in a new issue