mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-06-14 08:29:34 +00:00
Phasor: support SSI263 speech for Mockingboard mode (#777)
. Improved DEVICE_SELECT' I/O support (including Echo+). . SSI263_Read() only for Phasor in Phasor mode. . save-state: v6 (Phasor unit): phasor mode extended. SSI263 (MB/Phasor) bug fix for when RESET/Power-cycle during phoneme playback. Logging: . improved for SSI263 . in CPU.cpp, added 'IRQ' / 'ISR-end'
This commit is contained in:
parent
22806c6c59
commit
9f49820a8d
|
@ -98,6 +98,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#endif
|
||||
#include "Video.h"
|
||||
#include "NTSC.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include "z80emu.h"
|
||||
#include "Z80VICE/z80.h"
|
||||
|
@ -105,6 +106,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
||||
#include "YamlHelper.h"
|
||||
|
||||
#define LOG_IRQ_TAKEN_AND_RTI 0
|
||||
|
||||
// 6502 Accumulator Bit Flags
|
||||
#define AF_SIGN 0x80
|
||||
#define AF_OVERFLOW 0x40
|
||||
|
@ -243,6 +246,10 @@ static __forceinline void DoIrqProfiling(DWORD uCycles)
|
|||
if(regs.ps & AF_INTERRUPT)
|
||||
return; // Still in Apple's ROM
|
||||
|
||||
#if LOG_IRQ_TAKEN_AND_RTI
|
||||
LogOutput("ISR-end\n\n");
|
||||
#endif
|
||||
|
||||
g_nCycleIrqEnd = g_nCumulativeCycles + uCycles;
|
||||
g_nCycleIrqTime = (UINT) (g_nCycleIrqEnd - g_nCycleIrqStart);
|
||||
|
||||
|
@ -442,6 +449,9 @@ static __forceinline void IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn,
|
|||
regs.pc = * (WORD*) (mem+0xFFFE);
|
||||
UINT uExtraCycles = 0; // Needed for CYC(a) macro
|
||||
CYC(7)
|
||||
#if defined(_DEBUG) && LOG_IRQ_TAKEN_AND_RTI
|
||||
LogOutput("IRQ\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
g_irqOnLastOpcodeCycle = false;
|
||||
|
|
|
@ -187,7 +187,8 @@ static bool g_bMBAvailable = false;
|
|||
|
||||
static SS_CARDTYPE g_SoundcardType = CT_Empty; // Use CT_Empty to mean: no soundcard
|
||||
static bool g_bPhasorEnable = false;
|
||||
static BYTE g_nPhasorMode = 0; // 0=Mockingboard emulation, 1=Phasor native
|
||||
enum PHASOR_MODE {PH_Mockingboard=0, PH_UNDEF1, PH_UNDEF2, PH_UNDEF3, PH_UNDEF4, PH_Phasor/*=5*/, PH_UNDEF6, PH_EchoPlus/*=7*/};
|
||||
static PHASOR_MODE g_phasorMode = PH_Mockingboard;
|
||||
static UINT g_PhasorClockScaleFactor = 1; // for save-state only
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -363,8 +364,7 @@ static void UpdateIFR(SY6522_AY8910* pMB, BYTE clr_ifr, BYTE set_ifr=0)
|
|||
// NB. Mockingboard generates IRQ on both 6522s:
|
||||
// . SSI263's IRQ (A/!R) is routed via the 2nd 6522 (at $Cx80) and must generate a 6502 IRQ (not NMI)
|
||||
// . SC-01's IRQ (A/!R) is also routed via a (2nd?) 6522
|
||||
// Phasor's SSI263 appears to be wired directly to the 6502's IRQ (ie. not via a 6522)
|
||||
// . I assume Phasor's 6522s just generate 6502 IRQs (not NMIs)
|
||||
// Phasor's SSI263 IRQ (A/!R) line is *also* wired directly to the 6502's IRQ (as well as the 6522's CA1)
|
||||
|
||||
if (bIRQ)
|
||||
CpuIrqAssert(IS_6522);
|
||||
|
@ -394,7 +394,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
|||
|
||||
if(g_bPhasorEnable)
|
||||
{
|
||||
int nAY_CS = (g_nPhasorMode & 1) ? (~(nValue >> 3) & 3) : 1;
|
||||
int nAY_CS = (g_phasorMode == PH_Phasor) ? (~(nValue >> 3) & 3) : 1;
|
||||
|
||||
if(nAY_CS & 1)
|
||||
AY8910_Write(nDevice, nReg, nValue, 0);
|
||||
|
@ -590,14 +590,14 @@ const BYTE CONTROL_MASK = 0x80;
|
|||
const BYTE ARTICULATION_MASK = 0x70;
|
||||
const BYTE AMPLITUDE_MASK = 0x0F;
|
||||
|
||||
static BYTE SSI263_Read(BYTE nDevice, BYTE nReg)
|
||||
static BYTE SSI263_Read(BYTE nDevice, ULONG nExecutedCycles)
|
||||
{
|
||||
SY6522_AY8910* pMB = &g_MB[nDevice];
|
||||
|
||||
// Regardless of register, just return inverted A/!R in bit7
|
||||
// . A/!R is low for IRQ
|
||||
|
||||
return pMB->SpeechChip.CurrentMode << 7;
|
||||
return MemReadFloatingBus(pMB->SpeechChip.CurrentMode & 1, nExecutedCycles);
|
||||
}
|
||||
|
||||
static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
||||
|
@ -609,12 +609,22 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
|||
case SSI_DURPHON:
|
||||
#if LOG_SSI263
|
||||
if(g_fh) fprintf(g_fh, "DUR = 0x%02X, PHON = 0x%02X\n\n", nValue>>6, nValue&PHONEME_MASK);
|
||||
LogOutput("DUR = %d, PHON = 0x%02X\n", nValue>>6, nValue&PHONEME_MASK);
|
||||
#endif
|
||||
|
||||
// Datasheet is not clear, but a write to DURPHON must clear the IRQ
|
||||
if (pMB->sy6522.PCR == 0x0C)
|
||||
UpdateIFR(pMB, IxR_PERIPHERAL);
|
||||
else // Phasor's SSI263.IRQ line appears to be wired directly to IRQ (Bypassing the 6522)
|
||||
// Notes:
|
||||
// . Phasor's text-to-speech playback has no CTL H->L
|
||||
// - ISR just writes CTL=0 (and new ART+AMP values), and writes DUR=x (and new PHON)
|
||||
// - since no CTL H->L, then DUR value doesn't take affect (so continue using previous)
|
||||
// - so the write to DURPHON must clear the IRQ
|
||||
// . Does a write of CTL=0 clear IRQ? (ie. CTL 0->0)
|
||||
// . Does a write of CTL=1 clear IRQ? (ie. CTL 0->1)
|
||||
// - SSI263 datasheet says: "Setting the Control bit (CTL) to a logic one puts the device into Power Down mode..."
|
||||
// . Does phoneme output only happen when CTL=0? (Otherwise device is in PD mode)
|
||||
|
||||
// SSI263 datasheet is not clear, but a write to DURPHON must clear the IRQ.
|
||||
// NB. For Mockingboard, A/!R is ack'ed by 6522's PCR handshake.
|
||||
if (g_bPhasorEnable && g_phasorMode == PH_Phasor)
|
||||
CpuIrqDeassert(IS_SPEECH);
|
||||
|
||||
pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin
|
||||
|
@ -623,7 +633,6 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
|||
|
||||
g_nSSI263Device = nDevice;
|
||||
|
||||
// Phoneme output not dependent on CONTROL bit
|
||||
SSI263_Play(nValue & PHONEME_MASK);
|
||||
break;
|
||||
case SSI_INFLECT:
|
||||
|
@ -632,6 +641,7 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
|||
#endif
|
||||
pMB->SpeechChip.Inflection = nValue;
|
||||
break;
|
||||
|
||||
case SSI_RATEINF:
|
||||
#if LOG_SSI263
|
||||
if(g_fh) fprintf(g_fh, "RATE = 0x%02X, INF = 0x%02X\n", nValue>>4, nValue&0x0F);
|
||||
|
@ -641,19 +651,40 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
|
|||
case SSI_CTTRAMP:
|
||||
#if LOG_SSI263
|
||||
if(g_fh) fprintf(g_fh, "CTRL = %d, ART = 0x%02X, AMP=0x%02X\n", nValue>>7, (nValue&ARTICULATION_MASK)>>4, nValue&LITUDE_MASK);
|
||||
//
|
||||
{
|
||||
bool H2L = (pMB->SpeechChip.CtrlArtAmp & CONTROL_MASK) && !(nValue & CONTROL_MASK);
|
||||
char newMode[20];
|
||||
sprintf_s(newMode, sizeof(newMode), "(new mode=%d)", pMB->SpeechChip.DurationPhoneme>>6);
|
||||
LogOutput("CTRL = %d->%d, ART = 0x%02X, AMP=0x%02X %s\n", pMB->SpeechChip.CtrlArtAmp>>7, nValue>>7, (nValue&ARTICULATION_MASK)>>4, nValue&LITUDE_MASK, H2L?newMode:"");
|
||||
}
|
||||
#endif
|
||||
if((pMB->SpeechChip.CtrlArtAmp & CONTROL_MASK) && !(nValue & CONTROL_MASK)) // H->L
|
||||
{
|
||||
pMB->SpeechChip.CurrentMode = pMB->SpeechChip.DurationPhoneme & DURATION_MODE_MASK;
|
||||
if (pMB->SpeechChip.CurrentMode == MODE_IRQ_DISABLED)
|
||||
{
|
||||
// "Disables A/!R output only; does not change previous A/!R response" (SSI263 datasheet)
|
||||
// CpuIrqDeassert(IS_SPEECH);
|
||||
}
|
||||
}
|
||||
|
||||
pMB->SpeechChip.CtrlArtAmp = nValue;
|
||||
|
||||
// "Setting the Control bit (CTL) to a logic one puts the device into Power Down mode..." (SSI263 datasheet)
|
||||
if (pMB->SpeechChip.CtrlArtAmp & CONTROL_MASK)
|
||||
{
|
||||
// CpuIrqDeassert(IS_SPEECH);
|
||||
// pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin
|
||||
}
|
||||
break;
|
||||
case SSI_FILFREQ:
|
||||
case SSI_FILFREQ: // RegAddr.b2=1 (b1 & b0 are: don't care)
|
||||
default:
|
||||
#if LOG_SSI263
|
||||
if(g_fh) fprintf(g_fh, "FFREQ = 0x%02X\n", nValue);
|
||||
#endif
|
||||
pMB->SpeechChip.FilterFreq = nValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -990,20 +1021,34 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter)
|
|||
//if(g_fh) fprintf(g_fh, "IRQ: Phoneme complete (0x%02X)\n\n", g_nCurrentActivePhoneme);
|
||||
#endif
|
||||
|
||||
if (g_nCurrentActivePhoneme < 0)
|
||||
continue; // On CTRL+RESET or power-cycle (during phoneme playback): ResetState() is called, which set g_nCurrentActivePhoneme=-1
|
||||
|
||||
SSI263Voice[g_nCurrentActivePhoneme].bActive = false;
|
||||
g_nCurrentActivePhoneme = -1;
|
||||
|
||||
// Phoneme complete, so generate IRQ if necessary
|
||||
SY6522_AY8910* pMB = &g_MB[g_nSSI263Device];
|
||||
|
||||
if (!g_bVotraxPhoneme && pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED)
|
||||
if (!g_bVotraxPhoneme)
|
||||
{
|
||||
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||
// Always set SSI263's D7 pin regardless of SSI263 mode (DR1:0), including MODE_IRQ_DISABLED
|
||||
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
|
||||
|
||||
if (pMB->sy6522.PCR == 0x0C)
|
||||
if (pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED)
|
||||
{
|
||||
if (pMB->sy6522.PCR == 0x0C && (!g_bPhasorEnable || (g_bPhasorEnable && g_phasorMode == PH_Mockingboard)))
|
||||
{
|
||||
UpdateIFR(pMB, 0, IxR_PERIPHERAL);
|
||||
else // Phasor's SSI263.IRQ line appears to be wired directly to IRQ (Bypassing the 6522)
|
||||
pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin (cleared by 6522's PCR CA1/CA2 handshake)
|
||||
// NB. Don't set CTL=1, as Mockingboard(SMS) speech doesn't work (sets MODE_IRQ_DISABLED mode)
|
||||
//pMB->SpeechChip.CtrlArtAmp |= CONTROL_MASK; // 6522's CA2 sets Power Down mode (pin 18), which sets Control bit
|
||||
}
|
||||
else if (g_bPhasorEnable && g_phasorMode == PH_Phasor) // Phasor's SSI263 IRQ (A/!R) line is *also* wired directly to the 6502's IRQ (as well as the 6522's CA1)
|
||||
{
|
||||
CpuIrqAssert(IS_SPEECH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1470,7 +1515,7 @@ static void ResetState()
|
|||
g_bMB_RegAccessedFlag = false;
|
||||
g_bMB_Active = false;
|
||||
|
||||
g_nPhasorMode = 0;
|
||||
g_phasorMode = PH_Mockingboard;
|
||||
g_PhasorClockScaleFactor = 1;
|
||||
|
||||
g_uLastMBUpdateCycle = 0;
|
||||
|
@ -1499,6 +1544,8 @@ void MB_Reset() // CTRL+RESET or power-cycle
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Echo+ mode - Phasor's 2nd 6522 is mapped to every 16-byte offset in $Cnxx (Echo+ has a single 6522 controlling two AY-3-8913's)
|
||||
|
||||
static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nExecutedCycles)
|
||||
{
|
||||
if (g_bFullSpeed)
|
||||
|
@ -1526,11 +1573,13 @@ static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULO
|
|||
if(nMB != 0) // Slot4 only
|
||||
return MemReadFloatingBus(nExecutedCycles);
|
||||
|
||||
int CS;
|
||||
if(g_nPhasorMode & 1)
|
||||
CS = ( ( nAddr & 0x80 ) >> 6 ) | ( ( nAddr & 0x10 ) >> 4 ); // 0, 1, 2 or 3
|
||||
else // Mockingboard Mode
|
||||
int CS = 0;
|
||||
if (g_phasorMode == PH_Mockingboard)
|
||||
CS = ( ( nAddr & 0x80 ) >> 7 ) + 1; // 1 or 2
|
||||
else if (g_phasorMode == PH_Phasor)
|
||||
CS = ( ( nAddr & 0x80 ) >> 6 ) | ( ( nAddr & 0x10 ) >> 4 ); // 0, 1, 2 or 3
|
||||
else if (g_phasorMode == PH_EchoPlus)
|
||||
CS = 2;
|
||||
|
||||
BYTE nRes = 0;
|
||||
|
||||
|
@ -1542,9 +1591,10 @@ static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULO
|
|||
|
||||
bool bAccessedDevice = (CS & 3) ? true : false;
|
||||
|
||||
if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x05)))
|
||||
if ((g_phasorMode == PH_Phasor) && ((nAddr & 0xD0) == 0x40)) // $Cn4x and $Cn6x (Mockingboard mode: SSI263.bit7 not readable)
|
||||
{
|
||||
nRes |= SSI263_Read(nMB, nAddr&0xf);
|
||||
_ASSERT(!bAccessedDevice);
|
||||
nRes = SSI263_Read(nMB*2+1, nExecutedCycles); // SSI263 only drives bit7
|
||||
bAccessedDevice = true;
|
||||
}
|
||||
|
||||
|
@ -1555,8 +1605,8 @@ static BYTE __stdcall MB_Read(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULO
|
|||
return SY6522_Read(nMB*NUM_DEVS_PER_MB + SY6522_DEVICE_A, nAddr&0xf);
|
||||
else if((nOffset >= SY6522B_Offset) && (nOffset <= (SY6522B_Offset+0x0F)))
|
||||
return SY6522_Read(nMB*NUM_DEVS_PER_MB + SY6522_DEVICE_B, nAddr&0xf);
|
||||
else if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x05)))
|
||||
return SSI263_Read(nMB, nAddr&0xf);
|
||||
// else if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x07)))
|
||||
// return SSI263_Read(nMB*2+1, nExecutedCycles); // SSI263 only drives bit7 -- TODO confirm with real MB h/w
|
||||
else
|
||||
return MemReadFloatingBus(nExecutedCycles);
|
||||
}
|
||||
|
@ -1592,10 +1642,12 @@ static BYTE __stdcall MB_Write(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL
|
|||
|
||||
int CS;
|
||||
|
||||
if(g_nPhasorMode & 1)
|
||||
CS = ( ( nAddr & 0x80 ) >> 6 ) | ( ( nAddr & 0x10 ) >> 4 ); // 0, 1, 2 or 3
|
||||
else // Mockingboard Mode
|
||||
if (g_phasorMode == PH_Mockingboard)
|
||||
CS = ( ( nAddr & 0x80 ) >> 7 ) + 1; // 1 or 2
|
||||
else if (g_phasorMode == PH_Phasor)
|
||||
CS = ( ( nAddr & 0x80 ) >> 6 ) | ( ( nAddr & 0x10 ) >> 4 ); // 0, 1, 2 or 3
|
||||
else if (g_phasorMode == PH_EchoPlus)
|
||||
CS = 2;
|
||||
|
||||
if(CS & 1)
|
||||
SY6522_Write(nMB*NUM_DEVS_PER_MB + SY6522_DEVICE_A, nAddr&0xf, nValue);
|
||||
|
@ -1603,8 +1655,16 @@ static BYTE __stdcall MB_Write(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL
|
|||
if(CS & 2)
|
||||
SY6522_Write(nMB*NUM_DEVS_PER_MB + SY6522_DEVICE_B, nAddr&0xf, nValue);
|
||||
|
||||
if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x05)))
|
||||
SSI263_Write(nMB*2+1, nAddr&0xf, nValue); // Second 6522 is used for speech chip
|
||||
int CS_SSI263 = (g_phasorMode == PH_Mockingboard) ? (nAddr & 0xE0) == 0x40 // Mockingboard: $Cn4x
|
||||
: (g_phasorMode == PH_Phasor) ? (nAddr & 0xC0) == 0x40 // Phasor: $Cn4x and $Cn6x
|
||||
: 0; // Echo+
|
||||
|
||||
if (CS_SSI263)
|
||||
{
|
||||
// NB. Mockingboard mode: writes to $Cn4x/SSI263 also get written to 1st 6522 (have confirmed on real Phasor h/w)
|
||||
_ASSERT( (g_phasorMode == PH_Mockingboard && (CS==0 || CS==1)) || (g_phasorMode == PH_Phasor && (CS==0)) );
|
||||
SSI263_Write(nMB*2+1, nAddr&0x7, nValue); // Second 6522 is used for speech chip
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1613,23 +1673,45 @@ static BYTE __stdcall MB_Write(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL
|
|||
SY6522_Write(nMB*NUM_DEVS_PER_MB + SY6522_DEVICE_A, nAddr&0xf, nValue);
|
||||
else if((nOffset >= SY6522B_Offset) && (nOffset <= (SY6522B_Offset+0x0F)))
|
||||
SY6522_Write(nMB*NUM_DEVS_PER_MB + SY6522_DEVICE_B, nAddr&0xf, nValue);
|
||||
else if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x05)))
|
||||
SSI263_Write(nMB*2+1, nAddr&0xf, nValue); // Second 6522 is used for speech chip
|
||||
else if((nOffset >= SSI263_Offset) && (nOffset <= (SSI263_Offset+0x07)))
|
||||
SSI263_Write(nMB*2+1, nAddr&0x7, nValue); // Second 6522 is used for speech chip -- TODO confirm with real MB h/w that writes go to 1st 6522
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Phasor's DEVICE SELECT' logic:
|
||||
// . if addr.[b3]==1, then clear the card's mode bits b2:b0
|
||||
// . if any of addr.[b2:b0] are a logic 1, then set these bits in the card's mode
|
||||
//
|
||||
// Example DEVICE SELECT' accesses for Phasor in slot-4: (from empirical observations on real Phasor h/w)
|
||||
// 1)
|
||||
// . RESET -> Mockingboard mode (b#000)
|
||||
// . $C0C5 -> Phasor mode (b#101)
|
||||
// 2)
|
||||
// . RESET -> Mockingboard mode (b#000)
|
||||
// . $C0C1, then $C0C4 (or $C0C4, then $C0C1) -> Phasor mode (b#101)
|
||||
// . $C0C2 -> Echo+ mode (b#111)
|
||||
// . $C0C5 -> remaing in Echo+ mode (b#111)
|
||||
// So $C0C5 seemingly results in 2 different modes.
|
||||
//
|
||||
|
||||
static BYTE __stdcall PhasorIO(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, ULONG nExecutedCycles)
|
||||
{
|
||||
if(!g_bPhasorEnable)
|
||||
if (!g_bPhasorEnable)
|
||||
return MemReadFloatingBus(nExecutedCycles);
|
||||
|
||||
if(g_nPhasorMode < 2)
|
||||
g_nPhasorMode = nAddr & 1;
|
||||
UINT bits = (UINT) g_phasorMode;
|
||||
if (nAddr & 8)
|
||||
bits = 0;
|
||||
bits |= (nAddr & 7);
|
||||
g_phasorMode = (PHASOR_MODE) bits;
|
||||
|
||||
g_PhasorClockScaleFactor = (nAddr & 4) ? 2 : 1;
|
||||
if (g_phasorMode == PH_Mockingboard || g_phasorMode == PH_EchoPlus)
|
||||
g_PhasorClockScaleFactor = 1;
|
||||
else if (g_phasorMode == PH_Phasor)
|
||||
g_PhasorClockScaleFactor = 2;
|
||||
|
||||
AY8910_InitClock((int)(Get6502BaseClock() * g_PhasorClockScaleFactor));
|
||||
|
||||
|
@ -1972,7 +2054,8 @@ void MB_GetSnapshot_v1(SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot)
|
|||
// 3: Added: Unit state - GH#320
|
||||
// 4: Added: 6522 timerIrqDelay - GH#652
|
||||
// 5: Added: Unit state-B (Phasor only) - GH#659
|
||||
const UINT kUNIT_VERSION = 5;
|
||||
// 6: Changed SS_YAML_KEY_PHASOR_MODE from (0,1) to (0,5,7)
|
||||
const UINT kUNIT_VERSION = 6;
|
||||
|
||||
const UINT NUM_MB_UNITS = 2;
|
||||
const UINT NUM_PHASOR_UNITS = 2;
|
||||
|
@ -2235,7 +2318,7 @@ void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot)
|
|||
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||
|
||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR, g_PhasorClockScaleFactor);
|
||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASOR_MODE, g_nPhasorMode);
|
||||
yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASOR_MODE, g_phasorMode);
|
||||
|
||||
for(UINT i=0; i<NUM_PHASOR_UNITS; i++)
|
||||
{
|
||||
|
@ -2269,7 +2352,16 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version
|
|||
throw std::string("Card: wrong version");
|
||||
|
||||
g_PhasorClockScaleFactor = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR);
|
||||
g_nPhasorMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_MODE);
|
||||
|
||||
UINT phasorMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_MODE);
|
||||
if (version < 6)
|
||||
{
|
||||
if (phasorMode == 0)
|
||||
phasorMode = PH_Mockingboard;
|
||||
else
|
||||
phasorMode = PH_Phasor;
|
||||
}
|
||||
g_phasorMode = (PHASOR_MODE) phasorMode;
|
||||
|
||||
AY8910UpdateSetCycles();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user