From 69151a2aff9d10dee3d4e07c6634df79df3780e3 Mon Sep 17 00:00:00 2001 From: tomcw Date: Wed, 3 Jan 2024 21:22:25 +0000 Subject: [PATCH] MB/Phasor: support AY(s) driving bus for 6522 PortA (ie. for the PSG READ function) . Bump MB/Phasor save-state unit to v11 . Tested against mb-audit v1.50 --- source/6522.cpp | 11 ++--------- source/6522.h | 5 ++--- source/Mockingboard.cpp | 38 +++++++++++++++++++++++++++----------- source/Mockingboard.h | 2 ++ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/source/6522.cpp b/source/6522.cpp index d0a741b8..e1e0ff8c 100644 --- a/source/6522.cpp +++ b/source/6522.cpp @@ -128,13 +128,6 @@ 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 Phasor's 6522-AY8913 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; @@ -343,7 +336,7 @@ bool SY6522::IsTimer2Underflowed(BYTE reg) //----------------------------------------------------------------------------- -BYTE SY6522::Read(BYTE nReg) +BYTE SY6522::Read(BYTE nReg, bool isDrivingBus/*=false*/) { BYTE nValue = 0x00; @@ -353,7 +346,7 @@ BYTE SY6522::Read(BYTE nReg) nValue = m_regs.ORB | (m_regs.DDRB ^ 0xff); // Input bits read back as 1's (GH#1260) break; case 0x01: // IRA - nValue = m_regs.ORA; // NB. Inputs bits driven by AY8913 + nValue = m_regs.ORA | (isDrivingBus ? 0x00 : (m_regs.DDRA ^ 0xff)); // NB. Inputs bits driven by AY8913 if in PSG READ mode break; case 0x02: // DDRB nValue = m_regs.DDRB; diff --git a/source/6522.h b/source/6522.h index 7259a956..8e4d132c 100644 --- a/source/6522.h +++ b/source/6522.h @@ -28,7 +28,6 @@ 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); @@ -53,10 +52,10 @@ public: USHORT GetRegT1C(void) { return m_regs.TIMER1_COUNTER.w; } USHORT GetRegT2C(void) { return m_regs.TIMER2_COUNTER.w; } void GetRegs(BYTE regs[SIZE_6522_REGS]) { memcpy(®s[0], (BYTE*)&m_regs, SIZE_6522_REGS); } // For debugger - void SetRegORA(BYTE reg) { m_regs.ORA = reg; } + void SetRegIRA(BYTE reg) { m_regs.ORA = reg; } bool IsTimer1IrqDelay(void) { return m_timer1IrqDelay ? true : false; } - BYTE Read(BYTE nReg); + BYTE Read(BYTE nReg, bool isDrivingBus = false); void Write(BYTE nReg, BYTE nValue); void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index c37698f2..40e3dca2 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -252,7 +252,7 @@ void MockingboardCard::WriteToORB(BYTE subunit, BYTE subunitForAY/*=0*/) AY8913_Write(subunit, AY8913_DEVICE_B, value); if (nAY_CS == 0) - m_MBSubUnit[subunit].sy6522.UpdatePortAForHiZ(); + m_MBSubUnit[subunit].isDrivingBus = false; } else { @@ -310,16 +310,19 @@ void MockingboardCard::AY8913_Write(BYTE subunit, BYTE ay, BYTE value) break; case AY_READ: // 5: READ FROM PSG (need to set DDRA to input) + pMB->isDrivingBus = true; // Initially default to true + if (QueryType() != CT_MegaAudio) { if (pMB->isChipSelected[ay] && pMB->isAYLatchedAddressValid[ay]) - r6522.SetRegORA(AYReadReg(subunit, ay, pMB->nAYCurrentRegister[ay]) & (r6522.GetReg(SY6522::rDDRA) ^ 0xff)); + r6522.SetRegIRA(AYReadReg(subunit, ay, pMB->nAYCurrentRegister[ay]) & (r6522.GetReg(SY6522::rDDRA) ^ 0xff)); else - r6522.UpdatePortAForHiZ(); + pMB->isDrivingBus = false; } else { - r6522.SetRegORA(0x00); // Reads not supported. + r6522.SetRegIRA(0x00); // Reads not supported. Bus not driven. + pMB->isDrivingBus = false; } if (m_phasorEnable && m_phasorMode == PH_Phasor) // GH#1192 @@ -327,7 +330,7 @@ void MockingboardCard::AY8913_Write(BYTE subunit, BYTE ay, BYTE value) if (ay == AY8913_DEVICE_A) { if (pMB->isChipSelected[AY8913_DEVICE_B] && pMB->isAYLatchedAddressValid[AY8913_DEVICE_B]) - r6522.SetRegORA(r6522.GetReg(SY6522::rORA) | (AYReadReg(subunit, AY8913_DEVICE_B, pMB->nAYCurrentRegister[AY8913_DEVICE_B]) & (r6522.GetReg(SY6522::rDDRA) ^ 0xff))); + r6522.SetRegIRA(r6522.GetReg(SY6522::rORA) | (AYReadReg(subunit, AY8913_DEVICE_B, pMB->nAYCurrentRegister[AY8913_DEVICE_B]) & (r6522.GetReg(SY6522::rDDRA) ^ 0xff))); } } break; @@ -379,8 +382,8 @@ void MockingboardCard::AY8913_Write(BYTE subunit, BYTE ay, BYTE value) state = nAYFunc; - if (state == AY_INACTIVE && m_phasorEnable) // Phasor(even in MB mode) will read PortA inputs as high. - r6522.UpdatePortAForHiZ(); // Float high any PortA input bits (GH#1193) + if (state == AY_INACTIVE) // Mockingboard or Phasor(any mode) will read PortA inputs as high. + pMB->isDrivingBus = false; } //----------------------------------------------------------------------------- @@ -638,10 +641,10 @@ BYTE MockingboardCard::IOReadInternal(WORD PC, WORD nAddr, BYTE bWrite, BYTE nVa BYTE nRes = 0; if (CS & 1) - nRes |= m_MBSubUnit[SY6522_DEVICE_A].sy6522.Read(nAddr & 0xf); + nRes |= m_MBSubUnit[SY6522_DEVICE_A].sy6522.Read(nAddr & 0xf, m_MBSubUnit[SY6522_DEVICE_A].isDrivingBus); if (CS & 2) - nRes |= m_MBSubUnit[SY6522_DEVICE_B].sy6522.Read(nAddr & 0xf); + nRes |= m_MBSubUnit[SY6522_DEVICE_B].sy6522.Read(nAddr & 0xf, m_MBSubUnit[SY6522_DEVICE_B].isDrivingBus); bool bAccessedDevice = (CS & 3) ? true : false; @@ -668,7 +671,7 @@ BYTE MockingboardCard::IOReadInternal(WORD PC, WORD nAddr, BYTE bWrite, BYTE nVa // NB. Mockingboard: SSI263.bit7 not readable (TODO: check this with real h/w) const BYTE subunit = QueryType() == CT_SDMusic ? SY6522_DEVICE_A : !(nAddr & 0x80) ? SY6522_DEVICE_A : SY6522_DEVICE_B; const BYTE reg = nAddr & 0xf; - return m_MBSubUnit[subunit].sy6522.Read(reg); + return m_MBSubUnit[subunit].sy6522.Read(reg, m_MBSubUnit[subunit].isDrivingBus); } //----------------------------------------------------------------------------- @@ -1151,7 +1154,8 @@ UINT MockingboardCard::AY8910_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, BYTE // "Chip Select A" + "Chip Select B" // "Reg Address Latch Valid A" + "Reg Address Latch Valid B" // Changed at AppleWin 1.30.14 -const UINT kUNIT_VERSION = 10; +//11: Added: "Bus Driven by AY" +const UINT kUNIT_VERSION = 11; #define SS_YAML_KEY_MB_UNIT "Unit" #define SS_YAML_KEY_AY_CURR_REG "AY Current Register" @@ -1167,6 +1171,7 @@ const UINT kUNIT_VERSION = 10; #define SS_YAML_KEY_SPEECH_IRQ "Speech IRQ Pending" // v8: deprecated #define SS_YAML_KEY_TIMER1_ACTIVE "Timer1 Active" // v8: move to 6522 sub-unit #define SS_YAML_KEY_TIMER2_ACTIVE "Timer2 Active" // v8: move to 6522 sub-unit +#define SS_YAML_KEY_BUS_DRIVEN "Bus Driven by AY" #define SS_YAML_KEY_PHASOR_UNIT "Unit" #define SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR "Clock Scale Factor" // v6: deprecated @@ -1231,6 +1236,7 @@ void MockingboardCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister[0]); // save all 8 bits (even though top 4 bits should be 0) yamlSaveHelper.SaveBool(SS_YAML_KEY_CS_A, pMB->isChipSelected[0]); yamlSaveHelper.SaveBool(SS_YAML_KEY_LATCH_ADDR_VALID_A, pMB->isAYLatchedAddressValid[0]); + yamlSaveHelper.SaveBool(SS_YAML_KEY_BUS_DRIVEN, pMB->isDrivingBus); } } @@ -1297,6 +1303,10 @@ bool MockingboardCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version pMB->isAYLatchedAddressValid[0] = yamlLoadHelper.LoadBool(SS_YAML_KEY_LATCH_ADDR_VALID_A); } + pMB->isDrivingBus = (pMB->state[0] == AY_READ); + if (version >= 11) + pMB->isDrivingBus = yamlLoadHelper.LoadBool(SS_YAML_KEY_BUS_DRIVEN); + yamlLoadHelper.PopMap(); } @@ -1336,6 +1346,8 @@ void MockingboardCard::Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveBool(SS_YAML_KEY_CS_B, pMB->isChipSelected[1]); yamlSaveHelper.SaveBool(SS_YAML_KEY_LATCH_ADDR_VALID_A, pMB->isAYLatchedAddressValid[0]); yamlSaveHelper.SaveBool(SS_YAML_KEY_LATCH_ADDR_VALID_B, pMB->isAYLatchedAddressValid[1]); + + yamlSaveHelper.SaveBool(SS_YAML_KEY_BUS_DRIVEN, pMB->isDrivingBus); } } @@ -1430,6 +1442,10 @@ bool MockingboardCard::Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT pMB->isAYLatchedAddressValid[1] = yamlLoadHelper.LoadBool(SS_YAML_KEY_LATCH_ADDR_VALID_B); } + pMB->isDrivingBus = (pMB->state[0] == AY_READ || pMB->state[1] == AY_READ); + if (version >= 11) + pMB->isDrivingBus = yamlLoadHelper.LoadBool(SS_YAML_KEY_BUS_DRIVEN); + yamlLoadHelper.PopMap(); } diff --git a/source/Mockingboard.h b/source/Mockingboard.h index 50c87a63..84a4bf21 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -87,6 +87,7 @@ private: MockingboardUnitState_e state[NUM_AY8913_PER_SUBUNIT]; // AY's PSG function bool isAYLatchedAddressValid[NUM_AY8913_PER_SUBUNIT]; bool isChipSelected[NUM_AY8913_PER_SUBUNIT]; + bool isDrivingBus; MB_SUBUNIT(UINT slot, SS_CARDTYPE type) : sy6522(slot, type == CT_MegaAudio), ssi263(slot) { @@ -102,6 +103,7 @@ private: isAYLatchedAddressValid[0] = isAYLatchedAddressValid[1] = false; // after AY reset isChipSelected[0] = type == CT_Phasor ? false : true; // Only Phasor is false, all other MB variants are true isChipSelected[1] = false; + isDrivingBus = false; } };