mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-12-22 09:30:15 +00:00
Support MegaAudio card for testing mb-audit (PR #1211)
Differences compared to Mockingboard: . TIMER1 underflows to $FFFE before it's reloaded with latch. . TIMER1's LATCH=$0000 gets interpreted as $FFFF. . Partial TIMER2 support: IFR.T2 gets set on underflow. But T2 reads as 0x00FF. . AY register reads are unsupported (always read as 0). Config->Sound: show 'MEGA Audio' in drop-down menus only if it was specified on the cmd line.
This commit is contained in:
parent
33185f3f2b
commit
273d07d83f
@ -110,7 +110,16 @@ USHORT SY6522::SetTimerSyncEvent(BYTE reg, USHORT timerLatch)
|
||||
if (syncEvent->m_active)
|
||||
g_SynchronousEventMgr.Remove(syncEvent->m_id);
|
||||
|
||||
syncEvent->SetCycles(timerLatch + kExtraTimerCycles + opcodeCycleAdjust);
|
||||
if (m_isMegaAudio)
|
||||
{
|
||||
if (reg == rT1CH && timerLatch == 0x0000)
|
||||
timerLatch = 0xFFFF; // MegaAudio && T1.LATCH=0: use 0xFFFF (or maybe 0x10000?)
|
||||
syncEvent->SetCycles(timerLatch + kExtraMegaAudioTimerCycles + opcodeCycleAdjust); // MegaAudio asserts IRQ 1 cycle late!
|
||||
}
|
||||
else
|
||||
{
|
||||
syncEvent->SetCycles(timerLatch + kExtraTimerCycles + opcodeCycleAdjust);
|
||||
}
|
||||
g_SynchronousEventMgr.Insert(syncEvent);
|
||||
|
||||
// It doesn't matter if this overflows (ie. >0xFFFF), since on completion of current opcode it'll be corrected
|
||||
@ -260,10 +269,21 @@ bool SY6522::CheckTimerUnderflow(USHORT& counter, int& timerIrqDelay, const USHO
|
||||
|
||||
if (oldTimer >= 0 && timer < 0) // Underflow occurs for 0x0000 -> 0xFFFF
|
||||
{
|
||||
if (timer <= -2) // TIMER = 0xFFFE (or less)
|
||||
timerIrq = true;
|
||||
else // TIMER = 0xFFFF
|
||||
timerIrqDelay = 1; // ...so 1 cycle until IRQ
|
||||
if (m_isMegaAudio)
|
||||
{
|
||||
if (timer <= -3) // TIMER = 0xFFFD (or less)
|
||||
timerIrq = true;
|
||||
else // TIMER = 0xFFFF or 0xFFFE
|
||||
timerIrqDelay = 1; // ...so 1 or 2 cycles until IRQ
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timer <= -2) // TIMER = 0xFFFE (or less)
|
||||
timerIrq = true;
|
||||
else // TIMER = 0xFFFF
|
||||
timerIrqDelay = 1; // ...so 1 cycle until IRQ
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return timerIrq;
|
||||
@ -272,10 +292,19 @@ bool SY6522::CheckTimerUnderflow(USHORT& counter, int& timerIrqDelay, const USHO
|
||||
int SY6522::OnTimer1Underflow(USHORT& counter)
|
||||
{
|
||||
int timer = (int)(short)(counter);
|
||||
while (timer < -1)
|
||||
timer += (m_regs.TIMER1_LATCH.w + kExtraTimerCycles); // GH#651: account for underflowed cycles / GH#652: account for extra 2 cycles
|
||||
if (m_isMegaAudio)
|
||||
{
|
||||
const UINT timerLatch = m_regs.TIMER1_LATCH.w ? m_regs.TIMER1_LATCH.w : 0xFFFF; // MegaAudio && T1.LATCH=0: use 0xFFFF (or maybe 0x10000?)
|
||||
while (timer < -2)
|
||||
timer += (timerLatch + kExtraMegaAudioTimerCycles); // MegaAudio asserts IRQ 1 cycle late!
|
||||
}
|
||||
else
|
||||
{
|
||||
while (timer < -1)
|
||||
timer += (m_regs.TIMER1_LATCH.w + kExtraTimerCycles); // GH#651: account for underflowed cycles / GH#652: account for extra 2 cycles
|
||||
}
|
||||
counter = (USHORT)timer;
|
||||
return (timer == -1) ? 1 : 0; // timer1IrqDelay
|
||||
return (timer < 0) ? 1 : 0; // timer1IrqDelay
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -349,9 +378,11 @@ BYTE SY6522::Read(BYTE nReg)
|
||||
case 0x08: // TIMER2L
|
||||
nValue = GetTimer2Counter(nReg) & 0xff;
|
||||
UpdateIFR(IxR_TIMER2);
|
||||
if (m_isMegaAudio) nValue = 0xFF; // MegaAudio: Timer2 just reads as $00FF
|
||||
break;
|
||||
case 0x09: // TIMER2H
|
||||
nValue = GetTimer2Counter(nReg) >> 8;
|
||||
if (m_isMegaAudio) nValue = 0x00; // MegaAudio: Timer2 just reads as $00FF
|
||||
break;
|
||||
case 0x0a: // SERIAL_SHIFT
|
||||
break;
|
||||
@ -370,6 +401,8 @@ BYTE SY6522::Read(BYTE nReg)
|
||||
break;
|
||||
case 0x0e: // IER
|
||||
nValue = 0x80 | m_regs.IER; // GH#567
|
||||
if (m_isMegaAudio)
|
||||
nValue &= 0x7F;
|
||||
break;
|
||||
case 0x0f: // ORA_NO_HS
|
||||
nValue = m_regs.ORA;
|
||||
|
@ -3,7 +3,7 @@
|
||||
class SY6522
|
||||
{
|
||||
public:
|
||||
SY6522(UINT slot) : m_slot(slot)
|
||||
SY6522(UINT slot, bool isMegaAudio) : m_slot(slot), m_isMegaAudio(isMegaAudio)
|
||||
{
|
||||
for (UINT i = 0; i < kNumTimersPer6522; i++)
|
||||
m_syncEvent[i] = NULL;
|
||||
@ -143,4 +143,7 @@ private:
|
||||
|
||||
class SyncEvent* m_syncEvent[kNumTimersPer6522];
|
||||
UINT m_slot;
|
||||
bool m_isMegaAudio;
|
||||
|
||||
static const UINT kExtraMegaAudioTimerCycles = kExtraTimerCycles + 1;
|
||||
};
|
||||
|
@ -159,6 +159,8 @@ std::string Card::GetCardName(const SS_CARDTYPE cardType)
|
||||
return VidHDCard::GetSnapshotCardName();
|
||||
case CT_Uthernet2:
|
||||
return Uthernet2::GetSnapshotCardName();
|
||||
case CT_MegaAudio:
|
||||
return MockingboardCard::GetSnapshotCardNameMegaAudio();
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
@ -230,6 +232,10 @@ SS_CARDTYPE Card::GetCardType(const std::string & card)
|
||||
{
|
||||
return CT_Uthernet2;
|
||||
}
|
||||
else if (card == MockingboardCard::GetSnapshotCardNameMegaAudio())
|
||||
{
|
||||
return CT_MegaAudio;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Slots: Unknown card: " + card); // todo: don't throw - just ignore & continue
|
||||
|
@ -25,6 +25,7 @@ enum SS_CARDTYPE
|
||||
CT_SNESMAX, // 2 port Nintendo NES/SNES controller serial interface card
|
||||
CT_VidHD,
|
||||
CT_Uthernet2,
|
||||
CT_MegaAudio, // Soundcard
|
||||
};
|
||||
|
||||
enum SLOTS { SLOT0=0, SLOT1, SLOT2, SLOT3, SLOT4, SLOT5, SLOT6, SLOT7, NUM_SLOTS, SLOT_AUX, GAME_IO_CONNECTOR };
|
||||
|
@ -66,6 +66,7 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type)
|
||||
m_slot[slot] = m_pSSC = new CSuperSerialCard(slot);
|
||||
break;
|
||||
case CT_MockingboardC:
|
||||
case CT_MegaAudio:
|
||||
m_slot[slot] = new MockingboardCard(slot, type);
|
||||
break;
|
||||
case CT_GenericPrinter:
|
||||
|
@ -175,6 +175,8 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
|
||||
}
|
||||
if (strcmp(lpCmdLine, "hdc") == 0)
|
||||
g_cmdLine.slotInsert[slot] = CT_GenericHDD;
|
||||
if (strcmp(lpCmdLine, "megaaudio") == 0)
|
||||
g_cmdLine.slotInsert[slot] = CT_MegaAudio;
|
||||
if (strcmp(lpCmdLine, "parallel") == 0)
|
||||
{
|
||||
if (slot == SLOT1)
|
||||
|
@ -44,6 +44,16 @@ const char CPageSound::m_soundCardChoices[] = "Mockingboard\0"
|
||||
"SAM\0"
|
||||
"Empty\0";
|
||||
|
||||
// Don't reveal MegaAudio card unless it's been specified from the command line.
|
||||
// The reasons being are that:
|
||||
// . this card is purely for regression testing against mb-audit
|
||||
// . it's confusing to offer this to the end user
|
||||
const char CPageSound::m_soundCardChoicesEx[] = "Mockingboard\0"
|
||||
"Phasor\0"
|
||||
"SAM\0"
|
||||
"Empty\0"
|
||||
"MEGA Audio\0";
|
||||
|
||||
const char CPageSound::m_soundCardChoice_Unavailable[] = "Unavailable\0\0"; // doubly-null terminate
|
||||
|
||||
INT_PTR CALLBACK CPageSound::DlgProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
@ -105,6 +115,7 @@ INT_PTR CPageSound::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPAR
|
||||
case SC_PHASOR: newCard = CT_Phasor; break;
|
||||
case SC_SAM: newCard = CT_SAM; break;
|
||||
case SC_EMPTY: newCard = CT_Empty; break;
|
||||
case SC_MEGAAUDIO: newCard = CT_MegaAudio; break;
|
||||
default: _ASSERT(0); break;
|
||||
}
|
||||
|
||||
@ -166,28 +177,44 @@ CPageSound::SOUNDCARDCHOICE CPageSound::CardTypeToComboItem(SS_CARDTYPE card)
|
||||
case CT_Phasor: return SC_PHASOR;
|
||||
case CT_SAM: return SC_SAM;
|
||||
case CT_Empty: return SC_EMPTY;
|
||||
case CT_MegaAudio: return SC_MEGAAUDIO;
|
||||
default: _ASSERT(0); return SC_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
void CPageSound::InitOptions(HWND hWnd)
|
||||
{
|
||||
const SS_CARDTYPE slot4 = m_PropertySheetHelper.GetConfigNew().m_Slot[4];
|
||||
const SS_CARDTYPE slot5 = m_PropertySheetHelper.GetConfigNew().m_Slot[5];
|
||||
const SS_CARDTYPE slot4 = m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT4];
|
||||
const SS_CARDTYPE slot5 = m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT5];
|
||||
|
||||
bool isSlot4SoundCard = slot4 == CT_MockingboardC || slot4 == CT_Phasor || slot4 == CT_SAM || slot4 == CT_Empty;
|
||||
bool isSlot5SoundCard = slot5 == CT_MockingboardC || slot5 == CT_Phasor || slot5 == CT_SAM || slot5 == CT_Empty;
|
||||
|
||||
bool isSlot4SoundCardEx = slot4 == CT_MegaAudio;
|
||||
bool isSlot5SoundCardEx = slot5 == CT_MegaAudio;
|
||||
|
||||
if (isSlot4SoundCardEx || isSlot5SoundCardEx)
|
||||
{
|
||||
isSlot4SoundCardEx = isSlot5SoundCardEx = true; // if MegaAudio is visible in either, then make it available in both menus
|
||||
isSlot4SoundCard = isSlot5SoundCard = false;
|
||||
}
|
||||
|
||||
if (isSlot4SoundCard)
|
||||
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SOUNDCARD_SLOT4, m_soundCardChoices, (int)CardTypeToComboItem(slot4));
|
||||
else if (isSlot4SoundCardEx)
|
||||
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SOUNDCARD_SLOT4, m_soundCardChoicesEx, (int)CardTypeToComboItem(slot4));
|
||||
else
|
||||
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SOUNDCARD_SLOT4, m_soundCardChoice_Unavailable, 0);
|
||||
|
||||
if (isSlot5SoundCard)
|
||||
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SOUNDCARD_SLOT5, m_soundCardChoices, (int)CardTypeToComboItem(slot5));
|
||||
else if (isSlot5SoundCardEx)
|
||||
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SOUNDCARD_SLOT5, m_soundCardChoicesEx, (int)CardTypeToComboItem(slot5));
|
||||
else
|
||||
m_PropertySheetHelper.FillComboBox(hWnd, IDC_SOUNDCARD_SLOT5, m_soundCardChoice_Unavailable, 0);
|
||||
|
||||
bool enableMBVolume = slot4 == CT_MockingboardC || slot5 == CT_MockingboardC || slot4 == CT_Phasor || slot5 == CT_Phasor;
|
||||
bool enableMBVolume = slot4 == CT_MockingboardC || slot5 == CT_MockingboardC
|
||||
|| slot4 == CT_Phasor || slot5 == CT_Phasor
|
||||
|| slot4 == CT_MegaAudio || slot5 == CT_MegaAudio;
|
||||
EnableWindow(GetDlgItem(hWnd, IDC_MB_VOLUME), enableMBVolume ? TRUE : FALSE);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ protected:
|
||||
virtual void DlgCANCEL(HWND hWnd){}
|
||||
|
||||
private:
|
||||
enum SOUNDCARDCHOICE { SC_MOCKINGBOARD = 0, SC_PHASOR, SC_SAM, SC_EMPTY, _SOUNDCARD_MAX_CHOICES, SC_UNAVAILABLE };
|
||||
enum SOUNDCARDCHOICE { SC_MOCKINGBOARD = 0, SC_PHASOR, SC_SAM, SC_EMPTY, SC_MEGAAUDIO };
|
||||
|
||||
void InitOptions(HWND hWnd);
|
||||
SOUNDCARDCHOICE CardTypeToComboItem(SS_CARDTYPE card);
|
||||
@ -42,5 +42,6 @@ private:
|
||||
static const UINT VOLUME_MAX = 59;
|
||||
static const TCHAR m_soundchoices[];
|
||||
static const char m_soundCardChoices[];
|
||||
static const char m_soundCardChoicesEx[];
|
||||
static const char m_soundCardChoice_Unavailable[];
|
||||
};
|
||||
|
@ -62,7 +62,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
MockingboardCard::MockingboardCard(UINT slot, SS_CARDTYPE type) : Card(type, slot), m_MBSubUnit{slot, slot}
|
||||
MockingboardCard::MockingboardCard(UINT slot, SS_CARDTYPE type) : Card(type, slot), m_MBSubUnit{ {slot, type}, {slot, type} }
|
||||
{
|
||||
m_lastCumulativeCycle = 0;
|
||||
m_lastAYUpdateCycle = 0;
|
||||
@ -206,7 +206,8 @@ void MockingboardCard::WriteToORB(BYTE subunit)
|
||||
{
|
||||
BYTE value = m_MBSubUnit[subunit].sy6522.Read(SY6522::rORB);
|
||||
|
||||
if (subunit == 0 && // SC01 only at $Cn00 (not $Cn80)
|
||||
if ((QueryType() == CT_MockingboardC || QueryType() == CT_Phasor) && // Not CT_MegaAudio
|
||||
subunit == 0 && // SC01 only at $Cn00 (not $Cn80)
|
||||
m_MBSubUnit[subunit].sy6522.Read(SY6522::rPCR) == 0xB0)
|
||||
{
|
||||
// Votrax speech data
|
||||
@ -289,10 +290,17 @@ void MockingboardCard::AY8910_Write(BYTE subunit, BYTE ay, BYTE value)
|
||||
break;
|
||||
|
||||
case AY_READ: // 5: READ FROM PSG (need to set DDRA to input)
|
||||
if (pMB->isChipSelected[ay] && pMB->isAYLatchedAddressValid[ay])
|
||||
r6522.SetRegORA(AYReadReg(subunit, ay, pMB->nAYCurrentRegister[ay]) & (r6522.GetReg(SY6522::rDDRA) ^ 0xff));
|
||||
if (QueryType() != CT_MegaAudio)
|
||||
{
|
||||
if (pMB->isChipSelected[ay] && pMB->isAYLatchedAddressValid[ay])
|
||||
r6522.SetRegORA(AYReadReg(subunit, ay, pMB->nAYCurrentRegister[ay]) & (r6522.GetReg(SY6522::rDDRA) ^ 0xff));
|
||||
else
|
||||
r6522.UpdatePortAForHiZ();
|
||||
}
|
||||
else
|
||||
r6522.UpdatePortAForHiZ();
|
||||
{
|
||||
r6522.SetRegORA(0x00); // Reads not supported.
|
||||
}
|
||||
|
||||
if (m_phasorEnable && m_phasorMode == PH_Phasor) // GH#1192
|
||||
{
|
||||
@ -748,10 +756,13 @@ BYTE MockingboardCard::IOWriteInternal(WORD PC, WORD nAddr, BYTE bWrite, BYTE nV
|
||||
WriteToORB(subunit);
|
||||
|
||||
#if !DBG_MB_SS_CARD
|
||||
if (nAddr & 0x40)
|
||||
m_MBSubUnit[1].ssi263.Write(nAddr&0x7, nValue); // 2nd 6522 is used for 1st speech chip
|
||||
if (nAddr & 0x20)
|
||||
m_MBSubUnit[0].ssi263.Write(nAddr&0x7, nValue); // 1st 6522 is used for 2nd speech chip
|
||||
if (QueryType() == CT_MockingboardC || QueryType() == CT_Phasor) // Not CT_MegaAudio
|
||||
{
|
||||
if (nAddr & 0x40)
|
||||
m_MBSubUnit[1].ssi263.Write(nAddr & 0x7, nValue); // 2nd 6522 is used for 1st speech chip
|
||||
if (nAddr & 0x20)
|
||||
m_MBSubUnit[0].ssi263.Write(nAddr & 0x7, nValue); // 1st 6522 is used for 2nd speech chip
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@ -821,10 +832,10 @@ BYTE MockingboardCard::PhasorIOInternal(WORD PC, WORD nAddr, BYTE bWrite, BYTE n
|
||||
|
||||
void MockingboardCard::InitializeIO(LPBYTE pCxRomPeripheral)
|
||||
{
|
||||
if (QueryType() == CT_MockingboardC)
|
||||
RegisterIoHandler(m_slot, IO_Null, IO_Null, IORead, IOWrite, this, NULL);
|
||||
else // Phasor
|
||||
if (QueryType() == CT_Phasor)
|
||||
RegisterIoHandler(m_slot, PhasorIO, PhasorIO, IORead, IOWrite, this, NULL);
|
||||
else // All other Mockingboard variants
|
||||
RegisterIoHandler(m_slot, IO_Null, IO_Null, IORead, IOWrite, this, NULL);
|
||||
|
||||
if (g_bDisableDirectSound || g_bDisableDirectSoundMockingboard)
|
||||
return;
|
||||
@ -932,6 +943,7 @@ int MockingboardCard::MB_SyncEventCallbackInternal(int id, int /*cycles*/, ULONG
|
||||
pMB->sy6522.StartTimer1();
|
||||
if (pMB->sy6522.IsTimer1IrqDelay())
|
||||
return 0x0001; // T1C=0xFFFF, which is really -1, as there's 1 cycle until underflow occurs
|
||||
// TODO: can also be 0x0002 for MegaAudio
|
||||
return pMB->sy6522.GetRegT1C() + SY6522::kExtraTimerCycles;
|
||||
}
|
||||
|
||||
@ -1146,6 +1158,12 @@ std::string MockingboardCard::GetSnapshotCardNamePhasor(void)
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string MockingboardCard::GetSnapshotCardNameMegaAudio(void)
|
||||
{
|
||||
static const std::string name("MEGA Audio");
|
||||
return name;
|
||||
}
|
||||
|
||||
void MockingboardCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||
{
|
||||
if (QueryType() == CT_Phasor)
|
||||
@ -1153,7 +1171,11 @@ void MockingboardCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
||||
|
||||
//
|
||||
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_slot, kUNIT_VERSION);
|
||||
std::string cardName = GetSnapshotCardName();
|
||||
if (QueryType() == CT_MegaAudio)
|
||||
cardName = GetSnapshotCardNameMegaAudio();
|
||||
|
||||
YamlSaveHelper::Slot slot(yamlSaveHelper, cardName, m_slot, kUNIT_VERSION);
|
||||
|
||||
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
||||
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
|
||||
static std::string GetSnapshotCardName(void);
|
||||
static std::string GetSnapshotCardNamePhasor(void);
|
||||
static std::string GetSnapshotCardNameMegaAudio(void);
|
||||
|
||||
private:
|
||||
enum MockingboardUnitState_e { AY_NOP0, AY_NOP1, AY_INACTIVE, AY_READ, AY_NOP4, AY_NOP5, AY_WRITE, AY_LATCH };
|
||||
@ -83,7 +84,7 @@ private:
|
||||
bool isAYLatchedAddressValid[NUM_AY8913_PER_SUBUNIT];
|
||||
bool isChipSelected[NUM_AY8913_PER_SUBUNIT];
|
||||
|
||||
MB_SUBUNIT(UINT slot) : sy6522(slot), ssi263(slot)
|
||||
MB_SUBUNIT(UINT slot, SS_CARDTYPE type) : sy6522(slot, type == CT_MegaAudio), ssi263(slot)
|
||||
{
|
||||
nAY8910Number = 0;
|
||||
// sy6522 & ssi263 have already been default constructed
|
||||
@ -95,7 +96,7 @@ private:
|
||||
nAYCurrentRegister[0] = nAYCurrentRegister[1] = 0; // not valid
|
||||
state[0] = state[1] = AY_INACTIVE;
|
||||
isAYLatchedAddressValid[0] = isAYLatchedAddressValid[1] = false; // after AY reset
|
||||
isChipSelected[0] = type == CT_MockingboardC ? true : false;
|
||||
isChipSelected[0] = type == CT_Phasor ? false : true; // Only Phasor is false, all other MB variants are true
|
||||
isChipSelected[1] = false;
|
||||
}
|
||||
};
|
||||
|
@ -42,7 +42,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
bool MockingboardCardManager::IsMockingboard(UINT slot)
|
||||
{
|
||||
SS_CARDTYPE type = GetCardMgr().QuerySlot(slot);
|
||||
return type == CT_MockingboardC || type == CT_Phasor;
|
||||
return type == CT_MockingboardC || type == CT_Phasor || type == CT_MegaAudio;
|
||||
}
|
||||
|
||||
void MockingboardCardManager::ReinitializeClock(void)
|
||||
|
@ -775,6 +775,11 @@ static void RepeatInitialization(void)
|
||||
GetCardMgr().Insert(SLOT3, g_cmdLine.slotInsert[SLOT3]);
|
||||
}
|
||||
|
||||
if (g_cmdLine.slotInsert[SLOT4] != CT_Empty)
|
||||
{
|
||||
GetCardMgr().Insert(SLOT4, g_cmdLine.slotInsert[SLOT4]);
|
||||
}
|
||||
|
||||
if (g_cmdLine.slotInsert[SLOT5] != CT_Empty)
|
||||
{
|
||||
if (GetCardMgr().QuerySlot(SLOT5) != CT_Disk2) // Ignore if already got Disk2 in slot 5
|
||||
|
Loading…
Reference in New Issue
Block a user