mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-02-16 17:35:39 +00:00
Merge branch 'master' of https://github.com/trzy/Supermodel
This commit is contained in:
commit
6b0d5c453a
|
@ -1443,6 +1443,10 @@
|
||||||
</inputs>
|
</inputs>
|
||||||
</hardware>
|
</hardware>
|
||||||
<roms>
|
<roms>
|
||||||
|
<patches>
|
||||||
|
<!-- Prevent "rolling start" scrolling glitch -->
|
||||||
|
<patch region="crom" bits="32" offset="0x14BDB8" value="0x20B201E0" />
|
||||||
|
</patches>
|
||||||
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
||||||
<file offset="0" name="epr-19691.20" crc32="0x83523B89" />
|
<file offset="0" name="epr-19691.20" crc32="0x83523B89" />
|
||||||
<file offset="2" name="epr-19690.19" crc32="0x25F007FE" />
|
<file offset="2" name="epr-19690.19" crc32="0x25F007FE" />
|
||||||
|
@ -1531,6 +1535,8 @@
|
||||||
<patches>
|
<patches>
|
||||||
<!-- Secret debug menu -->
|
<!-- Secret debug menu -->
|
||||||
<patch region="crom" bits="32" offset="0x199DE8" value="0x00050208" />
|
<patch region="crom" bits="32" offset="0x199DE8" value="0x00050208" />
|
||||||
|
<!-- Prevent "rolling start" scrolling glitch -->
|
||||||
|
<patch region="crom" bits="32" offset="0x14BDF4" value="0x20B201E0" />
|
||||||
</patches>
|
</patches>
|
||||||
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
||||||
<file offset="0" name="epr-19734.20" crc32="0xBE897336" />
|
<file offset="0" name="epr-19734.20" crc32="0xBE897336" />
|
||||||
|
@ -1563,6 +1569,10 @@
|
||||||
</inputs>
|
</inputs>
|
||||||
</hardware>
|
</hardware>
|
||||||
<roms>
|
<roms>
|
||||||
|
<patches>
|
||||||
|
<!-- Prevent "rolling start" scrolling glitch -->
|
||||||
|
<patch region="crom" bits="32" offset="0x146350" value="0x20B201E0" />
|
||||||
|
</patches>
|
||||||
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
||||||
<file offset="0" name="epr-19607a.20" crc32="0x24301A12" />
|
<file offset="0" name="epr-19607a.20" crc32="0x24301A12" />
|
||||||
<file offset="2" name="epr-19608a.19" crc32="0x1426160E" />
|
<file offset="2" name="epr-19608a.19" crc32="0x1426160E" />
|
||||||
|
@ -1636,6 +1646,10 @@
|
||||||
</inputs>
|
</inputs>
|
||||||
</hardware>
|
</hardware>
|
||||||
<roms>
|
<roms>
|
||||||
|
<patches>
|
||||||
|
<!-- Prevent "rolling start" scrolling glitch -->
|
||||||
|
<patch region="crom" bits="32" offset="0x14E3F0" value="0x20B201E0" />
|
||||||
|
</patches>
|
||||||
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
||||||
<file offset="0" name="epr-20095a.20" crc32="0x58C7E393" />
|
<file offset="0" name="epr-20095a.20" crc32="0x58C7E393" />
|
||||||
<file offset="2" name="epr-20094a.19" crc32="0xDBF17A43" />
|
<file offset="2" name="epr-20094a.19" crc32="0xDBF17A43" />
|
||||||
|
@ -1684,6 +1698,10 @@
|
||||||
</inputs>
|
</inputs>
|
||||||
</hardware>
|
</hardware>
|
||||||
<roms>
|
<roms>
|
||||||
|
<patches>
|
||||||
|
<!-- Prevent "rolling start" scrolling glitch -->
|
||||||
|
<patch region="crom" bits="32" offset="0x14E014" value="0x20B201E0" />
|
||||||
|
</patches>
|
||||||
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
<region name="crom" stride="8" chunk_size="2" byte_swap="true">
|
||||||
<file offset="0" name="epr-20095.20" crc32="0x44467BC1" />
|
<file offset="0" name="epr-20095.20" crc32="0x44467BC1" />
|
||||||
<file offset="2" name="epr-20094.19" crc32="0x299B6257" />
|
<file offset="2" name="epr-20094.19" crc32="0x299B6257" />
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
namespace Debugger
|
namespace Debugger
|
||||||
{
|
{
|
||||||
// Instruction templates
|
// Instruction templates
|
||||||
static char *templates[5][256] = {
|
static const char *templates[5][256] = {
|
||||||
{
|
{
|
||||||
// Table 0: single byte instructions
|
// Table 0: single byte instructions
|
||||||
"NOP","LD BC,@a","LD (BC),A","INC BC","INC B","DEC B","LD B,@d","RLCA",
|
"NOP","LD BC,@a","LD (BC),A","INC BC","INC B","DEC B","LD B,@d","RLCA",
|
||||||
|
@ -393,10 +393,10 @@ namespace Debugger
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0xCB:
|
case 0xCB:
|
||||||
templ = templates[1][m_bus->Read8(dAddr++)];
|
templ = (char*)templates[1][m_bus->Read8(dAddr++)];
|
||||||
break;
|
break;
|
||||||
case 0xED:
|
case 0xED:
|
||||||
templ = templates[2][m_bus->Read8(dAddr++)];
|
templ = (char*)templates[2][m_bus->Read8(dAddr++)];
|
||||||
break;
|
break;
|
||||||
case 0xDD:
|
case 0xDD:
|
||||||
xyChr = 'X';
|
xyChr = 'X';
|
||||||
|
@ -405,10 +405,10 @@ namespace Debugger
|
||||||
{
|
{
|
||||||
offs = m_bus->Read8(dAddr++);
|
offs = m_bus->Read8(dAddr++);
|
||||||
notJump = true;
|
notJump = true;
|
||||||
templ = templates[4][m_bus->Read8(dAddr++)];
|
templ = (char*)templates[4][m_bus->Read8(dAddr++)];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
templ = templates[3][nextCode];
|
templ = (char*)templates[3][nextCode];
|
||||||
break;
|
break;
|
||||||
case 0xFD:
|
case 0xFD:
|
||||||
xyChr = 'Y';
|
xyChr = 'Y';
|
||||||
|
@ -417,13 +417,13 @@ namespace Debugger
|
||||||
{
|
{
|
||||||
offs = m_bus->Read8(dAddr++);
|
offs = m_bus->Read8(dAddr++);
|
||||||
notJump = true;
|
notJump = true;
|
||||||
templ = templates[4][m_bus->Read8(dAddr++)];
|
templ = (char*)templates[4][m_bus->Read8(dAddr++)];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
templ = templates[3][nextCode];
|
templ = (char*)templates[3][nextCode];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
templ = templates[0][opcode];
|
templ = (char*)templates[0][opcode];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2949,12 +2949,7 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
|
||||||
|
|
||||||
// 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');
|
||||||
uint32_t real3DPCIID = game.real3d_pci_id;
|
GPU.SetStepping(stepping);
|
||||||
if (0 == real3DPCIID)
|
|
||||||
{
|
|
||||||
real3DPCIID = stepping >= 0x20 ? CReal3D::PCIID::Step2x : CReal3D::PCIID::Step1x;
|
|
||||||
}
|
|
||||||
GPU.SetStepping(stepping, real3DPCIID);
|
|
||||||
|
|
||||||
// MPEG board (if present)
|
// MPEG board (if present)
|
||||||
if (rom_set.get_rom("mpeg_program").size)
|
if (rom_set.get_rom("mpeg_program").size)
|
||||||
|
|
|
@ -27,10 +27,10 @@
|
||||||
*
|
*
|
||||||
* PCI IDs
|
* PCI IDs
|
||||||
* -------
|
* -------
|
||||||
* It appears that Step 2.0 returns a different PCI ID depending on whether
|
* It appears that accessing the PCI configuration space returns the PCI ID
|
||||||
* the PCI configuration space or DMA register are accessed. For example,
|
* of Mercury (0x16C311DB) on Step 1.x and the DMA device (0x178611DB) on
|
||||||
* Virtual On 2 expects 0x178611DB from the PCI configuration header but
|
* Step 2.x, while accessing the Step 2.x DMA device register returns the
|
||||||
* 0x16C311DB from the DMA device.
|
* PCI ID of Mercury. Step 2.x games by AM3 expect this behavior.
|
||||||
*
|
*
|
||||||
* To-Do List
|
* To-Do List
|
||||||
* ----------
|
* ----------
|
||||||
|
@ -628,7 +628,8 @@ void CReal3D::WriteDMARegister32(unsigned reg, uint32_t data)
|
||||||
case 0x10: // command register
|
case 0x10: // command register
|
||||||
if ((data&0x20000000)) // DMA ID command
|
if ((data&0x20000000)) // DMA ID command
|
||||||
{
|
{
|
||||||
dmaData = pciID;
|
// Games requesting PCI ID via the DMA device expect 0x16C311DB, even on step 2.x boards
|
||||||
|
dmaData = PCIID::Step1x;
|
||||||
DebugLog("Real3D: DMA ID command issued (ATTENTION: make sure we're returning the correct value), PC=%08X, LR=%08X\n", ppc_get_pc(), ppc_get_lr());
|
DebugLog("Real3D: DMA ID command issued (ATTENTION: make sure we're returning the correct value), PC=%08X, LR=%08X\n", ppc_get_pc(), ppc_get_lr());
|
||||||
}
|
}
|
||||||
else if ((data&0x80000000))
|
else if ((data&0x80000000))
|
||||||
|
@ -921,7 +922,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, uint32_t pciIDValue)
|
void CReal3D::SetStepping(int stepping)
|
||||||
{
|
{
|
||||||
step = stepping;
|
step = stepping;
|
||||||
if ((step!=0x10) && (step!=0x15) && (step!=0x20) && (step!=0x21))
|
if ((step!=0x10) && (step!=0x15) && (step!=0x20) && (step!=0x21))
|
||||||
|
@ -931,7 +932,7 @@ void CReal3D::SetStepping(int stepping, uint32_t pciIDValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set PCI ID
|
// Set PCI ID
|
||||||
pciID = pciIDValue;
|
pciID = stepping >= 0x20 ? PCIID::Step2x : PCIID::Step1x;
|
||||||
|
|
||||||
// Pass to renderer
|
// Pass to renderer
|
||||||
if (Render3D != NULL)
|
if (Render3D != NULL)
|
||||||
|
|
|
@ -68,10 +68,11 @@ public:
|
||||||
/*
|
/*
|
||||||
* PCI IDs
|
* PCI IDs
|
||||||
*
|
*
|
||||||
* The CReal3D object must be configured with the desired ID. Some Step 2.x
|
* The CReal3D object must be configured with the PCI ID of the ASIC directly
|
||||||
* appear to defy this and expect the 1.x ID. The symptom of this is that
|
* connected to the PCI slot; 0x16c311db for Step 1.x, 0x178611db for Step
|
||||||
* VBL is enabled briefly then disabled. This should be investigated further.
|
* 2.x. Requesting PCI ID via the DMA device on Step 2.x appears to return
|
||||||
* Perhaps a different ASIC's PCI ID is being read in these situations?
|
* the PCI ID of Mercury which is the ASIC connected to the PCI slot on Step
|
||||||
|
* 1.x, hence why some Step 2.x games appear to expect the 1.x ID.
|
||||||
*
|
*
|
||||||
* The vendor ID code 0x11db is Sega's.
|
* The vendor ID code 0x11db is Sega's.
|
||||||
*/
|
*/
|
||||||
|
@ -374,7 +375,7 @@ public:
|
||||||
uint32_t GetASICIDCode(ASIC asic) const;
|
uint32_t GetASICIDCode(ASIC asic) const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SetStepping(stepping, pciIDValue):
|
* SetStepping(stepping):
|
||||||
*
|
*
|
||||||
* 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
|
||||||
|
@ -383,13 +384,8 @@ public:
|
||||||
* 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, uint32_t pciIDValue);
|
void SetStepping(int stepping);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
** This file is part of Supermodel.
|
** This file is part of Supermodel.
|
||||||
**
|
**
|
||||||
** Supermodel is free software: you can redistribute it and/or modify it under
|
** 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
|
** 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)
|
** Software Foundation, either version 3 of the License, or (at your option)
|
||||||
** any later version.
|
** any later version.
|
||||||
**
|
**
|
||||||
|
@ -19,17 +19,17 @@
|
||||||
** You should have received a copy of the GNU General Public License along
|
** You should have received a copy of the GNU General Public License along
|
||||||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
** with Supermodel. If not, see <http://www.gnu.org/licenses/>.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SCSP.cpp
|
* SCSP.cpp
|
||||||
*
|
*
|
||||||
* WARNING: Here be dragons! Tread carefully. Enabling/disabling things may
|
* WARNING: Here be dragons! Tread carefully. Enabling/disabling things may
|
||||||
* break save state support.
|
* break save state support.
|
||||||
*
|
*
|
||||||
* SCSP (Sega Custom Sound Processor) emulation. This code was generously
|
* SCSP (Sega Custom Sound Processor) emulation. This code was generously
|
||||||
* donated by ElSemi. Interfaces directly to the 68K processor through
|
* donated by ElSemi. Interfaces directly to the 68K processor through
|
||||||
* callbacks. Some minor interface changes were made (external global variables
|
* callbacks. Some minor interface changes were made (external global variables
|
||||||
* were removed).
|
* were removed).
|
||||||
*
|
*
|
||||||
* The MIDI input buffer has been increased from 8 (which I assume is the
|
* The MIDI input buffer has been increased from 8 (which I assume is the
|
||||||
* actual size) in order to accommodate Model 3's PowerPC/68K communication.
|
* actual size) in order to accommodate Model 3's PowerPC/68K communication.
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SEGA Custom Sound Processor (SCSP) Emulation
|
SEGA Custom Sound Processor (SCSP) Emulation
|
||||||
by ElSemi.
|
by ElSemi.
|
||||||
Driven by MC68000
|
Driven by MC68000
|
||||||
|
@ -78,7 +78,7 @@ Anyways credit to R. Belmont and ElSemi for the code, and for being awesome emul
|
||||||
|
|
||||||
static const Util::Config::Node *s_config = 0;
|
static const Util::Config::Node *s_config = 0;
|
||||||
static bool s_multiThreaded = false;
|
static bool s_multiThreaded = false;
|
||||||
bool legacySound; // For LegacySound (SCSP DSP) config option.
|
bool legacySound; // For LegacySound (SCSP DSP) config option.
|
||||||
|
|
||||||
#define USEDSP
|
#define USEDSP
|
||||||
//#define RB_VOLUME
|
//#define RB_VOLUME
|
||||||
|
@ -88,8 +88,6 @@ bool legacySound; // For LegacySound (SCSP DSP) config option.
|
||||||
//#define CORRECT_FOR_18BIT_DAC
|
//#define CORRECT_FOR_18BIT_DAC
|
||||||
|
|
||||||
// These globals control the operation of the SCSP, they are no longer extern and are set through SCSP_SetBuffers(). --Bart
|
// These globals control the operation of the SCSP, they are no longer extern and are set through SCSP_SetBuffers(). --Bart
|
||||||
static double SoundClock; // Originally titled SysFPS; seems to be for the sound CPU.
|
|
||||||
static const double Freq = 76;
|
|
||||||
static float* bufferfl;
|
static float* bufferfl;
|
||||||
static float* bufferfr;
|
static float* bufferfr;
|
||||||
static float* bufferrl;
|
static float* bufferrl;
|
||||||
|
@ -214,7 +212,7 @@ static int TimCnt[3];
|
||||||
#define PLFOWS(slot) ((slot->data[0x9] >> 0x8) & 0x0003)
|
#define PLFOWS(slot) ((slot->data[0x9] >> 0x8) & 0x0003)
|
||||||
#define PLFOS(slot) ((slot->data[0x9] >> 0x5) & 0x000E) // Setting this to 14 seems to make FM more precise
|
#define PLFOS(slot) ((slot->data[0x9] >> 0x5) & 0x000E) // Setting this to 14 seems to make FM more precise
|
||||||
#define ALFOWS(slot) ((slot->data[0x9] >> 0x3) & 0x0003)
|
#define ALFOWS(slot) ((slot->data[0x9] >> 0x3) & 0x0003)
|
||||||
#define ALFOS(slot) ((slot->data[0x9] >> 0x0) & 0x0007)
|
#define ALFOS(slot) ((slot->data[0x9] >> 0x0) & 0x0007)
|
||||||
|
|
||||||
#define ISEL(slot) ((slot->data[0xA] >> 0x3) & 0x000F)
|
#define ISEL(slot) ((slot->data[0xA] >> 0x3) & 0x000F)
|
||||||
#define IMXL(slot) ((slot->data[0xA] >> 0x0) & 0x0007)
|
#define IMXL(slot) ((slot->data[0xA] >> 0x0) & 0x0007)
|
||||||
|
@ -349,7 +347,7 @@ void CheckPendingIRQ()
|
||||||
{
|
{
|
||||||
DWORD pend=SCSPs->data[0x20/2];
|
DWORD pend=SCSPs->data[0x20/2];
|
||||||
DWORD en=SCSPs->data[0x1e/2];
|
DWORD en=SCSPs->data[0x1e/2];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MIDI FIFO critical section
|
* MIDI FIFO critical section
|
||||||
*
|
*
|
||||||
|
@ -363,20 +361,20 @@ void CheckPendingIRQ()
|
||||||
{
|
{
|
||||||
//if (g_Config.multiThreaded)
|
//if (g_Config.multiThreaded)
|
||||||
// MIDILock->Unlock();
|
// MIDILock->Unlock();
|
||||||
|
|
||||||
//SCSP.data[0x20/2]|=0x8; //Hold midi line while there are commands pending
|
//SCSP.data[0x20/2]|=0x8; //Hold midi line while there are commands pending
|
||||||
|
|
||||||
//Int68kCB(IrqMidi);
|
//Int68kCB(IrqMidi);
|
||||||
//printf("68K: MIDI IRQ\n");
|
//printf("68K: MIDI IRQ\n");
|
||||||
//ErrorLogMessage("Midi");
|
//ErrorLogMessage("Midi");
|
||||||
|
|
||||||
SCSP->data[0x20 / 2] |= 8;
|
SCSP->data[0x20 / 2] |= 8;
|
||||||
pend |= 8;
|
pend |= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (g_Config.multiThreaded)
|
//if (g_Config.multiThreaded)
|
||||||
// MIDILock->Unlock();
|
// MIDILock->Unlock();
|
||||||
|
|
||||||
if(!pend)
|
if(!pend)
|
||||||
return;
|
return;
|
||||||
if(pend&0x40)
|
if(pend&0x40)
|
||||||
|
@ -606,7 +604,6 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
s_config = &config;
|
s_config = &config;
|
||||||
s_multiThreaded = config["MultiThreaded"].ValueAs<bool>();
|
s_multiThreaded = config["MultiThreaded"].ValueAs<bool>();
|
||||||
legacySound = config["LegacySoundDSP"].ValueAs<bool>();
|
legacySound = config["LegacySoundDSP"].ValueAs<bool>();
|
||||||
SoundClock = Freq;
|
|
||||||
|
|
||||||
if(n==2)
|
if(n==2)
|
||||||
{
|
{
|
||||||
|
@ -632,7 +629,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
MidiOutR=MidiOutW=0;
|
MidiOutR=MidiOutW=0;
|
||||||
MidiOutFill=0;
|
MidiOutFill=0;
|
||||||
MidiInFill=0;
|
MidiInFill=0;
|
||||||
|
|
||||||
|
|
||||||
for(int i=0;i<0x400;++i)
|
for(int i=0;i<0x400;++i)
|
||||||
{
|
{
|
||||||
|
@ -641,7 +638,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
fcent=(double) 44100.0*exp2(fcent/1200.0);
|
fcent=(double) 44100.0*exp2(fcent/1200.0);
|
||||||
FNS_Table[i]=(UINT32)((float) (1<<SHIFT) *fcent);
|
FNS_Table[i]=(UINT32)((float) (1<<SHIFT) *fcent);
|
||||||
//FNS_Table[i]=(i>>(10-SHIFT))|(1<<SHIFT);
|
//FNS_Table[i]=(i>>(10-SHIFT))|(1<<SHIFT);
|
||||||
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 0x400; ++i) {
|
for (int i = 0; i < 0x400; ++i) {
|
||||||
float envDB = ((float)(3 * (i - 0x3ff))) / 32.0f;
|
float envDB = ((float)(3 * (i - 0x3ff))) / 32.0f;
|
||||||
|
@ -724,7 +721,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
// int a=1;
|
// int a=1;
|
||||||
//if(iTL==0x3a)
|
//if(iTL==0x3a)
|
||||||
// int a=1;
|
// int a=1;
|
||||||
|
|
||||||
LPANTABLE[i]=FIX((4.0*LPAN*TL*SDL));
|
LPANTABLE[i]=FIX((4.0*LPAN*TL*SDL));
|
||||||
RPANTABLE[i]=FIX((4.0*RPAN*TL*SDL));
|
RPANTABLE[i]=FIX((4.0*RPAN*TL*SDL));
|
||||||
}
|
}
|
||||||
|
@ -749,7 +746,7 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
scale=(double) (1<<EG_SHIFT);
|
scale=(double) (1<<EG_SHIFT);
|
||||||
DRTABLE[i]=(int) (step*scale);
|
DRTABLE[i]=(int) (step*scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0;i<32;++i)
|
for(int i=0;i<32;++i)
|
||||||
SCSPs[0].Slots[i].slot=i;
|
SCSPs[0].Slots[i].slot=i;
|
||||||
|
|
||||||
|
@ -764,14 +761,14 @@ bool SCSP_Init(const Util::Config::Node &config, int n)
|
||||||
TimCnt[0] = 0xffff;
|
TimCnt[0] = 0xffff;
|
||||||
TimCnt[1] = 0xffff;
|
TimCnt[1] = 0xffff;
|
||||||
TimCnt[2] = 0xffff;
|
TimCnt[2] = 0xffff;
|
||||||
|
|
||||||
// MIDI FIFO mutex
|
// MIDI FIFO mutex
|
||||||
MIDILock = CThread::CreateMutex();
|
MIDILock = CThread::CreateMutex();
|
||||||
if (NULL == MIDILock)
|
if (NULL == MIDILock)
|
||||||
{
|
{
|
||||||
return ErrorLog("Unable to create MIDI mutex!");
|
return ErrorLog("Unable to create MIDI mutex!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return OKAY;
|
return OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,7 +850,7 @@ void SCSP_UpdateReg(int reg)
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
case 9:
|
case 9:
|
||||||
SCSP->data[0x8 / 2] &= 0xf800;
|
SCSP->data[0x8 / 2] &= 0xf800;
|
||||||
break;
|
break;
|
||||||
case 0x12:
|
case 0x12:
|
||||||
case 0x13:
|
case 0x13:
|
||||||
|
@ -867,7 +864,7 @@ void SCSP_UpdateReg(int reg)
|
||||||
break;
|
break;
|
||||||
case 0x18:
|
case 0x18:
|
||||||
case 0x19:
|
case 0x19:
|
||||||
if(SCSP->Master)
|
if(SCSP->Master)
|
||||||
{
|
{
|
||||||
TimPris[0]=1<<((SCSPs->data[0x18/2]>>8)&0x7);
|
TimPris[0]=1<<((SCSPs->data[0x18/2]>>8)&0x7);
|
||||||
TimCnt[0]=((SCSPs->data[0x18/2]&0xfe)<<8)/*|(TimCnt[0]&0xff)*/;
|
TimCnt[0]=((SCSPs->data[0x18/2]&0xfe)<<8)/*|(TimCnt[0]&0xff)*/;
|
||||||
|
@ -875,7 +872,7 @@ void SCSP_UpdateReg(int reg)
|
||||||
break;
|
break;
|
||||||
case 0x1a:
|
case 0x1a:
|
||||||
case 0x1b:
|
case 0x1b:
|
||||||
if(SCSP->Master)
|
if(SCSP->Master)
|
||||||
{
|
{
|
||||||
TimPris[1]=1<<((SCSPs->data[0x1A/2]>>8)&0x7);
|
TimPris[1]=1<<((SCSPs->data[0x1A/2]>>8)&0x7);
|
||||||
TimCnt[1]=((SCSPs->data[0x1A/2]&0xfe)<<8)/*|(TimCnt[1]&0xff)*/;
|
TimCnt[1]=((SCSPs->data[0x1A/2]&0xfe)<<8)/*|(TimCnt[1]&0xff)*/;
|
||||||
|
@ -883,7 +880,7 @@ void SCSP_UpdateReg(int reg)
|
||||||
break;
|
break;
|
||||||
case 0x1C:
|
case 0x1C:
|
||||||
case 0x1D:
|
case 0x1D:
|
||||||
if(SCSP->Master)
|
if(SCSP->Master)
|
||||||
{
|
{
|
||||||
TimPris[2]=1<<((SCSPs->data[0x1C/2]>>8)&0x7);
|
TimPris[2]=1<<((SCSPs->data[0x1C/2]>>8)&0x7);
|
||||||
TimCnt[2]=((SCSPs->data[0x1C/2]&0xfe)<<8)/*|(TimCnt[2]&0xff)*/;
|
TimCnt[2]=((SCSPs->data[0x1C/2]&0xfe)<<8)/*|(TimCnt[2]&0xff)*/;
|
||||||
|
@ -891,7 +888,7 @@ void SCSP_UpdateReg(int reg)
|
||||||
break;
|
break;
|
||||||
case 0x22: //SCIRE
|
case 0x22: //SCIRE
|
||||||
case 0x23:
|
case 0x23:
|
||||||
if(SCSP->Master)
|
if(SCSP->Master)
|
||||||
{
|
{
|
||||||
SCSP->data[0x20 / 2] &= ~SCSP->data[0x22 / 2];
|
SCSP->data[0x20 / 2] &= ~SCSP->data[0x22 / 2];
|
||||||
//ResetInterrupts();
|
//ResetInterrupts();
|
||||||
|
@ -1029,7 +1026,7 @@ void SCSP_w8(unsigned int addr,unsigned char val)
|
||||||
{
|
{
|
||||||
*(unsigned char *) &(SCSP->datab[(addr&0xff)^1]) = val;
|
*(unsigned char *) &(SCSP->datab[(addr&0xff)^1]) = val;
|
||||||
SCSP_UpdateReg((addr^1)&0xff);
|
SCSP_UpdateReg((addr^1)&0xff);
|
||||||
}
|
}
|
||||||
else if(addr<0x700)
|
else if(addr<0x700)
|
||||||
SCSP->RINGBUF[(addr-0x600)/2]=val;
|
SCSP->RINGBUF[(addr-0x600)/2]=val;
|
||||||
else
|
else
|
||||||
|
@ -1096,7 +1093,7 @@ void SCSP_w16(unsigned int addr,unsigned short val)
|
||||||
*((unsigned short *)(SCSP->datab + ((addr & 0x3f)))) = val;
|
*((unsigned short *)(SCSP->datab + ((addr & 0x3f)))) = val;
|
||||||
SCSP_UpdateReg(addr & 0x3f);
|
SCSP_UpdateReg(addr & 0x3f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (addr < 0x700)
|
else if (addr < 0x700)
|
||||||
SCSP->RINGBUF[(addr - 0x600) / 2] = val;
|
SCSP->RINGBUF[(addr - 0x600) / 2] = val;
|
||||||
else
|
else
|
||||||
|
@ -1162,7 +1159,7 @@ void SCSP_w32(unsigned int addr,unsigned int val)
|
||||||
*(unsigned int *) &(SCSP->datab[addr&0xff]) = val;
|
*(unsigned int *) &(SCSP->datab[addr&0xff]) = val;
|
||||||
SCSP_UpdateReg(addr&0xff);
|
SCSP_UpdateReg(addr&0xff);
|
||||||
SCSP_UpdateReg((addr&0xff)+2);
|
SCSP_UpdateReg((addr&0xff)+2);
|
||||||
}
|
}
|
||||||
else if(addr<0x700)
|
else if(addr<0x700)
|
||||||
int a=1;
|
int a=1;
|
||||||
else
|
else
|
||||||
|
@ -1196,7 +1193,7 @@ unsigned char SCSP_r8(unsigned int addr)
|
||||||
int slot=addr/0x20;
|
int slot=addr/0x20;
|
||||||
addr&=0x1f;
|
addr&=0x1f;
|
||||||
SCSP_UpdateSlotRegR(slot,(addr^1)&0x1f);
|
SCSP_UpdateSlotRegR(slot,(addr^1)&0x1f);
|
||||||
|
|
||||||
v=*(unsigned char *) &(SCSP->Slots[slot].datab[addr^1]);
|
v=*(unsigned char *) &(SCSP->Slots[slot].datab[addr^1]);
|
||||||
//DebugLog("Slot %02X Reg %02X Read byte %02X",slot,addr^1,v);
|
//DebugLog("Slot %02X Reg %02X Read byte %02X",slot,addr^1,v);
|
||||||
}
|
}
|
||||||
|
@ -1204,8 +1201,8 @@ unsigned char SCSP_r8(unsigned int addr)
|
||||||
{
|
{
|
||||||
SCSP_UpdateRegR(addr&0xff);
|
SCSP_UpdateRegR(addr&0xff);
|
||||||
v= *(unsigned char *) &(SCSP->datab[(addr&0xff)^1]);
|
v= *(unsigned char *) &(SCSP->datab[(addr&0xff)^1]);
|
||||||
//ErrorLogMessage("SCSP Reg %02X Read byte %02X",addr&0xff,v);
|
//ErrorLogMessage("SCSP Reg %02X Read byte %02X",addr&0xff,v);
|
||||||
}
|
}
|
||||||
else if(addr<0x700)
|
else if(addr<0x700)
|
||||||
v=0;
|
v=0;
|
||||||
return v;
|
return v;
|
||||||
|
@ -1233,7 +1230,7 @@ unsigned short SCSP_r16(unsigned int addr)
|
||||||
SCSP_UpdateRegR(addr & 0x3f);
|
SCSP_UpdateRegR(addr & 0x3f);
|
||||||
v = *((UINT16 *)(SCSP->datab + ((addr & 0x3f))));
|
v = *((UINT16 *)(SCSP->datab + ((addr & 0x3f))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (addr < 0x700)
|
else if (addr < 0x700)
|
||||||
v = SCSP->RINGBUF[(addr - 0x600) / 2];
|
v = SCSP->RINGBUF[(addr - 0x600) / 2];
|
||||||
else
|
else
|
||||||
|
@ -1476,7 +1473,7 @@ signed int inline SCSP_UpdateSlot(_SLOT *slot)
|
||||||
|
|
||||||
if (!SDIR(slot))
|
if (!SDIR(slot))
|
||||||
{
|
{
|
||||||
if (ALFOS(slot) != 0)
|
if (ALFOS(slot) != 0)
|
||||||
{
|
{
|
||||||
sample = sample * ALFO_Step(&(slot->ALFO));
|
sample = sample * ALFO_Step(&(slot->ALFO));
|
||||||
sample >>= (SHIFT);
|
sample >>= (SHIFT);
|
||||||
|
@ -1516,7 +1513,7 @@ void SCSP_CpuRunScanline()
|
||||||
|
|
||||||
void SCSP_DoMasterSamples(int nsamples)
|
void SCSP_DoMasterSamples(int nsamples)
|
||||||
{
|
{
|
||||||
int slice = (int)(12000000. / (SoundClock*nsamples)); // 68K cycles/sample
|
const int slice = 11289600 / 44100; // 68K clocked at 11.2896MHz (45.1584MHz OSC / 4), which is 256 cycles/sample
|
||||||
static int lastdiff = 0;
|
static int lastdiff = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1563,7 +1560,7 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
#ifdef RB_VOLUME
|
#ifdef RB_VOLUME
|
||||||
smpfl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
smpfl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
||||||
smpfr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
smpfr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
smpfl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
smpfl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
||||||
smpfr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
smpfr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
||||||
|
@ -1600,7 +1597,7 @@ void SCSP_DoMasterSamples(int nsamples)
|
||||||
#ifdef RB_VOLUME
|
#ifdef RB_VOLUME
|
||||||
smprl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
smprl += (sample * volume[TL(slot) + pan_left[DIPAN(slot)]]) >> 17;
|
||||||
smprr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
smprr += (sample * volume[TL(slot) + pan_right[DIPAN(slot)]]) >> 17;
|
||||||
#else
|
#else
|
||||||
smprl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
smprl += (sample*LPANTABLE[Enc]) >> SHIFT;
|
||||||
smprr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
smprr += (sample*RPANTABLE[Enc]) >> SHIFT;
|
||||||
}
|
}
|
||||||
|
@ -1743,7 +1740,7 @@ void SCSP_MidiIn(BYTE val)
|
||||||
*/
|
*/
|
||||||
if (s_multiThreaded)
|
if (s_multiThreaded)
|
||||||
MIDILock->Lock();
|
MIDILock->Lock();
|
||||||
|
|
||||||
//DebugLog("Midi Buffer push %02X",val);
|
//DebugLog("Midi Buffer push %02X",val);
|
||||||
MidiStack[MidiW++]=val;
|
MidiStack[MidiW++]=val;
|
||||||
MidiW&=MIDI_STACK_SIZE_MASK;
|
MidiW&=MIDI_STACK_SIZE_MASK;
|
||||||
|
@ -1780,7 +1777,7 @@ unsigned char SCSP_MidiOutR()
|
||||||
|
|
||||||
if(MidiOutR==MidiOutW) // I don't think this needs to be a critical section...
|
if(MidiOutR==MidiOutW) // I don't think this needs to be a critical section...
|
||||||
return 0xff;
|
return 0xff;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MIDI FIFO critical section
|
* MIDI FIFO critical section
|
||||||
*/
|
*/
|
||||||
|
@ -1791,17 +1788,17 @@ unsigned char SCSP_MidiOutR()
|
||||||
//DebugLog("Midi Out Buffer pop %02X",val);
|
//DebugLog("Midi Out Buffer pop %02X",val);
|
||||||
MidiOutR&=31;
|
MidiOutR&=31;
|
||||||
--MidiOutFill;
|
--MidiOutFill;
|
||||||
|
|
||||||
if (s_multiThreaded)
|
if (s_multiThreaded)
|
||||||
MIDILock->Unlock();
|
MIDILock->Unlock();
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char SCSP_MidiOutFill()
|
unsigned char SCSP_MidiOutFill()
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MIDI FIFO critical section
|
* MIDI FIFO critical section
|
||||||
*/
|
*/
|
||||||
|
@ -1809,17 +1806,17 @@ unsigned char SCSP_MidiOutFill()
|
||||||
MIDILock->Lock();
|
MIDILock->Lock();
|
||||||
|
|
||||||
v = MidiOutFill;
|
v = MidiOutFill;
|
||||||
|
|
||||||
if (s_multiThreaded)
|
if (s_multiThreaded)
|
||||||
MIDILock->Unlock();
|
MIDILock->Unlock();
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char SCSP_MidiInFill()
|
unsigned char SCSP_MidiInFill()
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MIDI FIFO critical section
|
* MIDI FIFO critical section
|
||||||
*/
|
*/
|
||||||
|
@ -1827,10 +1824,10 @@ unsigned char SCSP_MidiInFill()
|
||||||
MIDILock->Lock();
|
MIDILock->Lock();
|
||||||
|
|
||||||
v = MidiInFill;
|
v = MidiInFill;
|
||||||
|
|
||||||
if (s_multiThreaded)
|
if (s_multiThreaded)
|
||||||
MIDILock->Unlock();
|
MIDILock->Unlock();
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1937,13 +1934,13 @@ unsigned int SCSP_Slave_r32(unsigned int addr)
|
||||||
void SCSP_SaveState(CBlockFile *StateFile)
|
void SCSP_SaveState(CBlockFile *StateFile)
|
||||||
{
|
{
|
||||||
StateFile->NewBlock("SCSP x 2", __FILE__);
|
StateFile->NewBlock("SCSP x 2", __FILE__);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save global variables.
|
* Save global variables.
|
||||||
*
|
*
|
||||||
* Difficult to say exactly what is necessary given that many things are
|
* Difficult to say exactly what is necessary given that many things are
|
||||||
* commented out and should not be enabled but I try to save as much as
|
* commented out and should not be enabled but I try to save as much as
|
||||||
* possible.
|
* possible.
|
||||||
*
|
*
|
||||||
* Things not saved:
|
* Things not saved:
|
||||||
*
|
*
|
||||||
|
@ -1965,7 +1962,7 @@ void SCSP_SaveState(CBlockFile *StateFile)
|
||||||
StateFile->Write(&MidiR, sizeof(MidiR));
|
StateFile->Write(&MidiR, sizeof(MidiR));
|
||||||
StateFile->Write(TimPris, sizeof(TimPris));
|
StateFile->Write(TimPris, sizeof(TimPris));
|
||||||
StateFile->Write(TimCnt, sizeof(TimCnt));
|
StateFile->Write(TimCnt, sizeof(TimCnt));
|
||||||
|
|
||||||
// Save both SCSP states
|
// Save both SCSP states
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
|
@ -1976,13 +1973,13 @@ void SCSP_SaveState(CBlockFile *StateFile)
|
||||||
StateFile->Write(&(SCSPs[i].DELAYBUF), sizeof(SCSPs[i].DELAYBUF));
|
StateFile->Write(&(SCSPs[i].DELAYBUF), sizeof(SCSPs[i].DELAYBUF));
|
||||||
StateFile->Write(&(SCSPs[i].DELAYPTR), sizeof(SCSPs[i].DELAYPTR));
|
StateFile->Write(&(SCSPs[i].DELAYPTR), sizeof(SCSPs[i].DELAYPTR));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Save each slot
|
// Save each slot
|
||||||
for (int j = 0; j < 32; j++)
|
for (int j = 0; j < 32; j++)
|
||||||
{
|
{
|
||||||
UINT64 baseOffset;
|
UINT64 baseOffset;
|
||||||
UINT8 egState;
|
UINT8 egState;
|
||||||
|
|
||||||
StateFile->Write(SCSPs[i].Slots[j].datab, sizeof(SCSPs[i].Slots[j].datab));
|
StateFile->Write(SCSPs[i].Slots[j].datab, sizeof(SCSPs[i].Slots[j].datab));
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].active), sizeof(SCSPs[i].Slots[j].active));
|
StateFile->Write(&(SCSPs[i].Slots[j].active), sizeof(SCSPs[i].Slots[j].active));
|
||||||
baseOffset = (UINT64) (SCSPs[i].Slots[j].base - SCSPs[i].SCSPRAM);
|
baseOffset = (UINT64) (SCSPs[i].Slots[j].base - SCSPs[i].SCSPRAM);
|
||||||
|
@ -1993,7 +1990,7 @@ void SCSP_SaveState(CBlockFile *StateFile)
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].Back), sizeof(SCSPs[i].Slots[j].Back));
|
StateFile->Write(&(SCSPs[i].Slots[j].Back), sizeof(SCSPs[i].Slots[j].Back));
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].slot), sizeof(SCSPs[i].Slots[j].slot));
|
StateFile->Write(&(SCSPs[i].Slots[j].slot), sizeof(SCSPs[i].Slots[j].slot));
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].Prev), sizeof(SCSPs[i].Slots[j].Prev));
|
StateFile->Write(&(SCSPs[i].Slots[j].Prev), sizeof(SCSPs[i].Slots[j].Prev));
|
||||||
|
|
||||||
// EG
|
// EG
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].EG.volume), sizeof(SCSPs[i].Slots[j].EG.volume));
|
StateFile->Write(&(SCSPs[i].Slots[j].EG.volume), sizeof(SCSPs[i].Slots[j].EG.volume));
|
||||||
egState = SCSPs[i].Slots[j].EG.state;
|
egState = SCSPs[i].Slots[j].EG.state;
|
||||||
|
@ -2006,18 +2003,18 @@ void SCSP_SaveState(CBlockFile *StateFile)
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].EG.DL), sizeof(SCSPs[i].Slots[j].EG.DL));
|
StateFile->Write(&(SCSPs[i].Slots[j].EG.DL), sizeof(SCSPs[i].Slots[j].EG.DL));
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].EG.EGHOLD), sizeof(SCSPs[i].Slots[j].EG.EGHOLD));
|
StateFile->Write(&(SCSPs[i].Slots[j].EG.EGHOLD), sizeof(SCSPs[i].Slots[j].EG.EGHOLD));
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].EG.LPLINK), sizeof(SCSPs[i].Slots[j].EG.LPLINK));
|
StateFile->Write(&(SCSPs[i].Slots[j].EG.LPLINK), sizeof(SCSPs[i].Slots[j].EG.LPLINK));
|
||||||
|
|
||||||
// PLFO
|
// PLFO
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].PLFO.phase), sizeof(SCSPs[i].Slots[j].PLFO.phase));
|
StateFile->Write(&(SCSPs[i].Slots[j].PLFO.phase), sizeof(SCSPs[i].Slots[j].PLFO.phase));
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].PLFO.phase_step), sizeof(SCSPs[i].Slots[j].PLFO.phase_step));
|
StateFile->Write(&(SCSPs[i].Slots[j].PLFO.phase_step), sizeof(SCSPs[i].Slots[j].PLFO.phase_step));
|
||||||
|
|
||||||
// ALFO
|
// ALFO
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].ALFO.phase), sizeof(SCSPs[i].Slots[j].ALFO.phase));
|
StateFile->Write(&(SCSPs[i].Slots[j].ALFO.phase), sizeof(SCSPs[i].Slots[j].ALFO.phase));
|
||||||
StateFile->Write(&(SCSPs[i].Slots[j].ALFO.phase_step), sizeof(SCSPs[i].Slots[j].ALFO.phase_step));
|
StateFile->Write(&(SCSPs[i].Slots[j].ALFO.phase_step), sizeof(SCSPs[i].Slots[j].ALFO.phase_step));
|
||||||
|
|
||||||
//when loading, make sure to compute lfo
|
//when loading, make sure to compute lfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// DSP
|
// DSP
|
||||||
StateFile->Write(&(SCSPs[i].DSP.RBP), sizeof(SCSPs[i].DSP.RBP));
|
StateFile->Write(&(SCSPs[i].DSP.RBP), sizeof(SCSPs[i].DSP.RBP));
|
||||||
StateFile->Write(&(SCSPs[i].DSP.RBL), sizeof(SCSPs[i].DSP.RBL));
|
StateFile->Write(&(SCSPs[i].DSP.RBL), sizeof(SCSPs[i].DSP.RBL));
|
||||||
|
@ -2042,7 +2039,7 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
ErrorLog("Unable to load SCSP state. Save state file is corrupt.");
|
ErrorLog("Unable to load SCSP state. Save state file is corrupt.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load global variables
|
// Load global variables
|
||||||
StateFile->Read(&IrqTimA, sizeof(IrqTimA));
|
StateFile->Read(&IrqTimA, sizeof(IrqTimA));
|
||||||
StateFile->Read(&IrqTimBC, sizeof(IrqTimBC));
|
StateFile->Read(&IrqTimBC, sizeof(IrqTimBC));
|
||||||
|
@ -2057,7 +2054,7 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
StateFile->Read(&MidiR, sizeof(MidiR));
|
StateFile->Read(&MidiR, sizeof(MidiR));
|
||||||
StateFile->Read(TimPris, sizeof(TimPris));
|
StateFile->Read(TimPris, sizeof(TimPris));
|
||||||
StateFile->Read(TimCnt, sizeof(TimCnt));
|
StateFile->Read(TimCnt, sizeof(TimCnt));
|
||||||
|
|
||||||
// Load both SCSP states
|
// Load both SCSP states
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
|
@ -2068,13 +2065,13 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
StateFile->Read(&(SCSPs[i].DELAYBUF), sizeof(SCSPs[i].DELAYBUF));
|
StateFile->Read(&(SCSPs[i].DELAYBUF), sizeof(SCSPs[i].DELAYBUF));
|
||||||
StateFile->Read(&(SCSPs[i].DELAYPTR), sizeof(SCSPs[i].DELAYPTR));
|
StateFile->Read(&(SCSPs[i].DELAYPTR), sizeof(SCSPs[i].DELAYPTR));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Load each slot
|
// Load each slot
|
||||||
for (int j = 0; j < 32; j++)
|
for (int j = 0; j < 32; j++)
|
||||||
{
|
{
|
||||||
UINT64 baseOffset;
|
UINT64 baseOffset;
|
||||||
UINT8 egState;
|
UINT8 egState;
|
||||||
|
|
||||||
StateFile->Read(SCSPs[i].Slots[j].datab, sizeof(SCSPs[i].Slots[j].datab));
|
StateFile->Read(SCSPs[i].Slots[j].datab, sizeof(SCSPs[i].Slots[j].datab));
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].active), sizeof(SCSPs[i].Slots[j].active));
|
StateFile->Read(&(SCSPs[i].Slots[j].active), sizeof(SCSPs[i].Slots[j].active));
|
||||||
StateFile->Read(&baseOffset, sizeof(baseOffset));
|
StateFile->Read(&baseOffset, sizeof(baseOffset));
|
||||||
|
@ -2085,7 +2082,7 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].Back), sizeof(SCSPs[i].Slots[j].Back));
|
StateFile->Read(&(SCSPs[i].Slots[j].Back), sizeof(SCSPs[i].Slots[j].Back));
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].slot), sizeof(SCSPs[i].Slots[j].slot));
|
StateFile->Read(&(SCSPs[i].Slots[j].slot), sizeof(SCSPs[i].Slots[j].slot));
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].Prev), sizeof(SCSPs[i].Slots[j].Prev));
|
StateFile->Read(&(SCSPs[i].Slots[j].Prev), sizeof(SCSPs[i].Slots[j].Prev));
|
||||||
|
|
||||||
// EG
|
// EG
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].EG.volume), sizeof(SCSPs[i].Slots[j].EG.volume));
|
StateFile->Read(&(SCSPs[i].Slots[j].EG.volume), sizeof(SCSPs[i].Slots[j].EG.volume));
|
||||||
StateFile->Read(&egState, sizeof(egState));
|
StateFile->Read(&egState, sizeof(egState));
|
||||||
|
@ -2098,11 +2095,11 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].EG.DL), sizeof(SCSPs[i].Slots[j].EG.DL));
|
StateFile->Read(&(SCSPs[i].Slots[j].EG.DL), sizeof(SCSPs[i].Slots[j].EG.DL));
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].EG.EGHOLD), sizeof(SCSPs[i].Slots[j].EG.EGHOLD));
|
StateFile->Read(&(SCSPs[i].Slots[j].EG.EGHOLD), sizeof(SCSPs[i].Slots[j].EG.EGHOLD));
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].EG.LPLINK), sizeof(SCSPs[i].Slots[j].EG.LPLINK));
|
StateFile->Read(&(SCSPs[i].Slots[j].EG.LPLINK), sizeof(SCSPs[i].Slots[j].EG.LPLINK));
|
||||||
|
|
||||||
// PLFO
|
// PLFO
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].PLFO.phase), sizeof(SCSPs[i].Slots[j].PLFO.phase));
|
StateFile->Read(&(SCSPs[i].Slots[j].PLFO.phase), sizeof(SCSPs[i].Slots[j].PLFO.phase));
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].PLFO.phase_step), sizeof(SCSPs[i].Slots[j].PLFO.phase_step));
|
StateFile->Read(&(SCSPs[i].Slots[j].PLFO.phase_step), sizeof(SCSPs[i].Slots[j].PLFO.phase_step));
|
||||||
|
|
||||||
// ALFO
|
// ALFO
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].ALFO.phase), sizeof(SCSPs[i].Slots[j].ALFO.phase));
|
StateFile->Read(&(SCSPs[i].Slots[j].ALFO.phase), sizeof(SCSPs[i].Slots[j].ALFO.phase));
|
||||||
StateFile->Read(&(SCSPs[i].Slots[j].ALFO.phase_step), sizeof(SCSPs[i].Slots[j].ALFO.phase_step));
|
StateFile->Read(&(SCSPs[i].Slots[j].ALFO.phase_step), sizeof(SCSPs[i].Slots[j].ALFO.phase_step));
|
||||||
|
@ -2110,7 +2107,7 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
// Recompute LFOs
|
// Recompute LFOs
|
||||||
Compute_LFO(&(SCSPs[i].Slots[j]));
|
Compute_LFO(&(SCSPs[i].Slots[j]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// DSP
|
// DSP
|
||||||
StateFile->Read(&(SCSPs[i].DSP.RBP), sizeof(SCSPs[i].DSP.RBP));
|
StateFile->Read(&(SCSPs[i].DSP.RBP), sizeof(SCSPs[i].DSP.RBP));
|
||||||
StateFile->Read(&(SCSPs[i].DSP.RBL), sizeof(SCSPs[i].DSP.RBL));
|
StateFile->Read(&(SCSPs[i].DSP.RBL), sizeof(SCSPs[i].DSP.RBL));
|
||||||
|
@ -2130,7 +2127,6 @@ void SCSP_LoadState(CBlockFile *StateFile)
|
||||||
|
|
||||||
void SCSP_SetBuffers(float *leftBufferPtr, float *rightBufferPtr, float* leftRearBufferPtr, float* rightRearBufferPtr, int bufferLength)
|
void SCSP_SetBuffers(float *leftBufferPtr, float *rightBufferPtr, float* leftRearBufferPtr, float* rightRearBufferPtr, int bufferLength)
|
||||||
{
|
{
|
||||||
SoundClock = Freq;
|
|
||||||
bufferfl = leftBufferPtr;
|
bufferfl = leftBufferPtr;
|
||||||
bufferfr = rightBufferPtr;
|
bufferfr = rightBufferPtr;
|
||||||
bufferrl = leftRearBufferPtr;
|
bufferrl = leftRearBufferPtr;
|
||||||
|
|
Loading…
Reference in a new issue