diff --git a/source/6522.cpp b/source/6522.cpp index 42a71cfd..25bd1cac 100644 --- a/source/6522.cpp +++ b/source/6522.cpp @@ -116,6 +116,13 @@ USHORT SY6522::SetTimerSyncEvent(BYTE reg, USHORT timerLatch) //----------------------------------------------------------------------------- +void SY6522::UpdatePortAForHiZ(void) +{ + BYTE ora = GetReg(SY6522::rORA); + ora |= GetReg(SY6522::rDDRA) ^ 0xff; // for any DDRA bits set as input (logical 0), then set them in ORA + SetRegORA(ora); // empirically bus floats high (or pull-up?) if no AY chip-selected (so DDRA=0x00 will read 0xFF as input) +} + void SY6522::UpdateIFR(BYTE clr_ifr, BYTE set_ifr /*= 0*/) { m_regs.IFR &= ~clr_ifr; diff --git a/source/6522.h b/source/6522.h index bf780b99..52a4c23b 100644 --- a/source/6522.h +++ b/source/6522.h @@ -28,6 +28,7 @@ public: void StopTimer2(void); bool IsTimer2Active(void) { return m_timer2Active; } + void UpdatePortAForHiZ(void); void UpdateIFR(BYTE clr_ifr, BYTE set_ifr = 0); void UpdateTimer1(USHORT clocks); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index d74fe563..78bbbab9 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -92,6 +92,7 @@ MockingboardCard::MockingboardCard(UINT slot, SS_CARDTYPE type) : Card(type, slo for (UINT i = 0; i < NUM_SUBUNITS_PER_MB; i++) { m_MBSubUnit[i].nAY8910Number = i; + m_MBSubUnit[i].Reset(QueryType()); const UINT id0 = i * SY6522::kNumTimersPer6522 + 0; // TIMER1 const UINT id1 = i * SY6522::kNumTimersPer6522 + 1; // TIMER2 m_MBSubUnit[i].sy6522.InitSyncEvents(m_syncEvent[id0], m_syncEvent[id1]); @@ -177,6 +178,29 @@ void MockingboardCard::Get6522IrqDescription(std::string& desc) //----------------------------------------------------------------------------- +// Notes on Phasor's AY-3-8913 chip-select & r/w: (GH#1192) +// ---------------------------------------------- +// +// Where: AY1 is the primary AY-3-8913 connected to 6522, and AY2 is the 2nd-ary. +// +// AFAICT, inputs to the Phasor GAL are: +// . ORB.b4:3 = Chip Select (CS) for AY1 & AY2 (active low) +// . ORB.b2:0 = PSG Function (RESET, INACTIVE, READ, WRITE, LATCH) +// . Phasor mode (Mockingboard, Echo+, Phasor-native) +// . Slot inputs (address, reset, etc) +// And outputs from the GAL are: +// . GAL CS' for AY1 & AY2 (not just passed-through, but dependent on PSG Function) +// (Not PSG Function - probably just passed-through from 6522 to the chip-selected AY-3-8913's) +// +// In Phasor-native mode, GAL logic: +// . AY2 LATCH func selects AY2 and AY1; sets latch addr for AY2 and AY1 +// . AY1 LATCH func selects AY1; deselects AY2; sets latch addr for AY1 +// . AY2 WRITE func writes AY2 if it's selected +// . AY1 WRITE func writes AY1; writes AY2 if it's selected +// +// EG, to do a "AY1 LATCH", then write 6522 ORB with b4:3=%01, b2:0=%111 +// + void MockingboardCard::WriteToORB(BYTE subunit) { BYTE value = m_MBSubUnit[subunit].sy6522.Read(SY6522::rORB); @@ -214,12 +238,7 @@ void MockingboardCard::WriteToORB(BYTE subunit) AY8910_Write(subunit, AY8913_DEVICE_B, value); if (nAY_CS == 0) - { - SY6522& r6522 = m_MBSubUnit[subunit].sy6522; - BYTE ora = r6522.GetReg(SY6522::rORA); - ora |= r6522.GetReg(SY6522::rDDRA) ^ 0xff; // for any DDRA bits set as input (logical 0), then set them in ORA - r6522.SetRegORA(ora); // empirically bus floats high (or pull-up?) if no AY chip-selected (so DDRA=0x00 will read 0xFF as input) - } + m_MBSubUnit[subunit].sy6522.UpdatePortAForHiZ(); } else { @@ -240,7 +259,7 @@ void MockingboardCard::AY8910_Write(BYTE subunit, BYTE ay, BYTE value) { // RESET: Reset AY8910 only AY8910_reset(subunit, ay); - pMB->Reset(); + pMB->Reset(QueryType()); } else { @@ -270,7 +289,7 @@ void MockingboardCard::AY8910_Write(BYTE subunit, BYTE ay, BYTE value) if (pMB->isChipSelected[ay] && pMB->isAYLatchedAddressValid[ay]) r6522.SetRegORA(AYReadReg(subunit, ay, pMB->nAYCurrentRegister[ay]) & (r6522.GetReg(SY6522::rDDRA) ^ 0xff)); else - r6522.SetRegORA(r6522.GetReg(SY6522::rDDRA) ^ 0xff); + r6522.UpdatePortAForHiZ(); break; case AY_WRITE: // 6: WRITE TO PSG @@ -510,7 +529,7 @@ void MockingboardCard::Reset(const bool powerCycle) // CTRL+RESET or power-cycle for (BYTE ay = 0; ay < NUM_AY8913_PER_SUBUNIT; ay++) AY8910_reset(subunit, ay); - m_MBSubUnit[subunit].Reset(); + m_MBSubUnit[subunit].Reset(QueryType()); m_MBSubUnit[subunit].ssi263.SetCardMode(PH_Mockingboard); // Revert to PH_Mockingboard mode m_MBSubUnit[subunit].ssi263.Reset(); } @@ -764,6 +783,12 @@ BYTE MockingboardCard::PhasorIOInternal(WORD PC, WORD nAddr, BYTE bWrite, BYTE n else if (m_phasorMode == PH_Phasor) m_phasorClockScaleFactor = 2; + if (m_phasorMode == PH_Mockingboard) + { + for (BYTE subunit = 0; subunit < NUM_SUBUNITS_PER_MB; subunit++) + m_MBSubUnit[subunit].isChipSelected[0] = true; + } + AY8910_InitClock((int)(Get6502BaseClock() * m_phasorClockScaleFactor)); for (UINT i = 0; i < NUM_SSI263; i++) diff --git a/source/Mockingboard.h b/source/Mockingboard.h index 77116182..f42d20a3 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -72,14 +72,16 @@ private: { nAY8910Number = 0; // sy6522 & ssi263 have already been default constructed + // Reset() called from MockingboardCard ctor } - void Reset(void) + void Reset(SS_CARDTYPE type) { nAYCurrentRegister[0] = nAYCurrentRegister[1] = 0; // not valid state[0] = state[1] = AY_INACTIVE; isAYLatchedAddressValid[0] = isAYLatchedAddressValid[1] = false; // after AY reset - isChipSelected[0] = isChipSelected[1] = false; + isChipSelected[0] = type == CT_MockingboardC ? true : false; + isChipSelected[1] = false; } };