From 729cd56093964eed045c68ba4496f664744ae19b Mon Sep 17 00:00:00 2001 From: tomcw Date: Fri, 22 Mar 2024 21:04:53 +0000 Subject: [PATCH] Add LanguageCardManager class --- source/CardManager.cpp | 19 +++--- source/CardManager.h | 7 +-- source/Debugger/Debugger_Display.cpp | 2 +- source/LanguageCard.cpp | 87 +++++++++++++++++++++++++--- source/LanguageCard.h | 32 +++++++++- source/Memory.cpp | 54 ++++------------- 6 files changed, 132 insertions(+), 69 deletions(-) diff --git a/source/CardManager.cpp b/source/CardManager.cpp index f641098e..f32eddae 100644 --- a/source/CardManager.cpp +++ b/source/CardManager.cpp @@ -116,21 +116,16 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type) m_slot[slot] = new Uthernet2(slot); break; case CT_LanguageCard: - _ASSERT(m_pLanguageCard == NULL); - if (m_pLanguageCard) break; // Only support one language card - m_slot[slot] = m_pLanguageCard = LanguageCardSlot0::create(slot); - break; case CT_LanguageCardIIe: - _ASSERT(m_pLanguageCard == NULL); - if (m_pLanguageCard) break; // Only support one language card - m_slot[slot] = m_pLanguageCard = LanguageCardUnit::create(slot); + _ASSERT(slot == SLOT0); + if (GetLanguageCardMgr().SetLanguageCard(type)) + m_slot[SLOT0] = GetLanguageCardMgr().GetLanguageCard(); break; case CT_Saturn128K: if (slot == SLOT0) { - _ASSERT(m_pLanguageCard == NULL); - if (m_pLanguageCard) break; // Only support one language card - m_slot[slot] = m_pLanguageCard = new Saturn128K(slot, Saturn128K::GetSaturnMemorySize()); + if (GetLanguageCardMgr().SetLanguageCard(type)) + m_slot[SLOT0] = GetLanguageCardMgr().GetLanguageCard(); } else { @@ -173,11 +168,11 @@ void CardManager::RemoveInternal(UINT slot) case CT_LanguageCard: case CT_LanguageCardIIe: _ASSERT(slot == SLOT0); - m_pLanguageCard = NULL; + GetLanguageCardMgr().SetLanguageCard(CT_Empty); break; case CT_Saturn128K: if (slot == SLOT0) - m_pLanguageCard = NULL; + GetLanguageCardMgr().SetLanguageCard(CT_Empty); break; case CT_Z80: m_pZ80Card = NULL; diff --git a/source/CardManager.h b/source/CardManager.h index 1c24354b..03e8591f 100644 --- a/source/CardManager.h +++ b/source/CardManager.h @@ -2,6 +2,7 @@ #include "Card.h" #include "Disk2CardManager.h" +#include "LanguageCard.h" #include "MockingboardCardManager.h" #include "Common.h" @@ -11,7 +12,6 @@ public: CardManager(void) : m_pMouseCard(NULL), m_pSSC(NULL), - m_pLanguageCard(NULL), m_pParallelPrinterCard(NULL), m_pZ80Card(NULL) { @@ -53,6 +53,7 @@ public: // Disk2CardManager& GetDisk2CardMgr(void) { return m_disk2CardMgr; } + LanguageCardManager& GetLanguageCardMgr(void) { return m_languageCardMgr; } MockingboardCardManager& GetMockingboardCardMgr(void) { return m_mockingboardCardMgr; } class CMouseInterface* GetMouseCard(void) { return m_pMouseCard; } bool IsMouseCardInstalled(void) { return m_pMouseCard != NULL; } @@ -61,8 +62,6 @@ public: class ParallelPrinterCard* GetParallelPrinterCard(void) { return m_pParallelPrinterCard; } bool IsParallelPrinterCardInstalled(void) { return m_pParallelPrinterCard != NULL; } - class LanguageCardUnit* GetLanguageCard(void) { return m_pLanguageCard; } - void InitializeIO(LPBYTE pCxRomPeripheral); void Destroy(void); void Reset(const bool powerCycle); @@ -78,10 +77,10 @@ private: Card* m_slot[NUM_SLOTS]; Card* m_aux; Disk2CardManager m_disk2CardMgr; + LanguageCardManager m_languageCardMgr; MockingboardCardManager m_mockingboardCardMgr; class CMouseInterface* m_pMouseCard; class CSuperSerialCard* m_pSSC; - class LanguageCardUnit* m_pLanguageCard; class ParallelPrinterCard* m_pParallelPrinterCard; class Z80Card* m_pZ80Card; }; diff --git a/source/Debugger/Debugger_Display.cpp b/source/Debugger/Debugger_Display.cpp index 37dd51a0..4c718f0a 100644 --- a/source/Debugger/Debugger_Display.cpp +++ b/source/Debugger/Debugger_Display.cpp @@ -2594,7 +2594,7 @@ void _DrawSoftSwitchLanguageCardBank( RECT & rect, const int iBankDisplay, int b int iActiveBank = -1; char cMemType = '?'; // Default to RAMWORKS if (GetCurrentExpansionMemType() == CT_RamWorksIII) { cMemType = 'r'; iActiveBank = GetRamWorksActiveBank(); } - if (GetCurrentExpansionMemType() == CT_Saturn128K) { cMemType = 's'; iActiveBank = GetCardMgr().GetLanguageCard()->GetActiveBank(); } + if (GetCurrentExpansionMemType() == CT_Saturn128K) { cMemType = 's'; iActiveBank = GetCardMgr().GetLanguageCardMgr().GetLanguageCard()->GetActiveBank(); } if (iActiveBank >= 0) { diff --git a/source/LanguageCard.cpp b/source/LanguageCard.cpp index f0da5dd6..9a5eb8be 100644 --- a/source/LanguageCard.cpp +++ b/source/LanguageCard.cpp @@ -44,16 +44,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Also see UTAII 6-6, where Firmware card and 16K RAM card are described. * . Sather refers to the Apple 16K RAM card, which is just the Apple Language Card. * - * Note: Consider adding a LangauageCardManager class: - * . would manage g_lastSlotToSetMainMemLC (so move out of Memory.cpp) - * . would manage reset for all cards (eg. II/II+'s LC is unaffected, whereas //e's LC is) - * . assist with debugger's display of "sNN" for active 16K bank - * Currently conclude that there's not much point. */ #include "StdAfx.h" #include "LanguageCard.h" +#include "CardManager.h" #include "Core.h" #include "CPU.h" // GH#700 #include "Log.h" @@ -128,7 +124,7 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu pLC->SetLastRamWrite( ((uAddr & 1) && !bWrite) ); // UTAIIe:5-23 pLC->SetLCMemMode(memmode); - const bool bCardChanged = GetLastSlotToSetMainMemLC() != SLOT0; + const bool bCardChanged = GetCardMgr().GetLanguageCardMgr().GetLastSlotToSetMainMemLC() != SLOT0; if (bCardChanged) { if (pLC->QueryType() == CT_LanguageCardIIe) @@ -410,7 +406,7 @@ BYTE __stdcall Saturn128K::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULO pLC->SetLastRamWrite(uAddr & 1); // Saturn differs from Apple's 16K LC: any access (LC is read-only) pLC->SetLCMemMode(memmode); - bBankChanged = GetLastSlotToSetMainMemLC() != uSlot; + bBankChanged = GetCardMgr().GetLanguageCardMgr().GetLastSlotToSetMainMemLC() != uSlot; if (bBankChanged) { ::SetMemMainLanguageCard(pLC->m_aSaturnBanks[pLC->m_uSaturnActiveBank], uSlot); @@ -529,3 +525,80 @@ UINT Saturn128K::GetSaturnMemorySize() { return g_uSaturnBanksFromCmdLine; } + +//------------------------------------- + +/* +* LangauageCardManager: +* . manage reset for all cards (eg. II/II+'s LC is unaffected, whereas //e's LC is) +* . manage lastSlotToSetMainMemLC +* . TODO: assist with debugger's display of "sNN" for active 16K bank +*/ + +void LanguageCardManager::Reset(const bool powerCycle /*=false*/) +{ + if (GetLanguageCard()) + GetLanguageCard()->SetLastRamWrite(0); + + if (IsApple2PlusOrClone(GetApple2Type()) && GetCardMgr().QuerySlot(SLOT0) == CT_Empty) + SetMemMode(0); + else + SetMemMode(LanguageCardUnit::kMemModeInitialState); + + // For power on: card's ctor will have set card's local memmode to LanguageCardUnit::kMemModeInitialState. + // For reset: II/II+ unaffected, so only for //e or above. + if (IsAppleIIeOrAbove(GetApple2Type())) + { + if (GetCardMgr().QuerySlot(SLOT0) != CT_Empty) // LC or Saturn + dynamic_cast(GetCardMgr().GetRef(SLOT0)).SetLCMemMode(GetMemMode() & MF_LANGCARD_MASK); + for (UINT i = SLOT1; i < NUM_SLOTS; i++) + { + if (GetCardMgr().QuerySlot(i) == CT_Saturn128K) + dynamic_cast(GetCardMgr().GetRef(i)).SetLCMemMode(GetMemMode() & MF_LANGCARD_MASK); + } + } +} + +void LanguageCardManager::SetMemModeFromSnapshot(void) +{ + // If multiple "Language Cards" (eg. LC+Saturn or 2xSaturn) then setup via the last card that selected the 16KB LC bank. + // NB. Skip if not Saturn card (ie. a LC), since LC's are only in slot0 and in the ctor it has called SetMainMemLanguageCard() + if (GetCardMgr().QuerySlot(m_lastSlotToSetMainMemLCFromSnapshot) == CT_Saturn128K) + { + Saturn128K& saturn = dynamic_cast(GetCardMgr().GetRef(m_lastSlotToSetMainMemLCFromSnapshot)); + saturn.SetMemMainLanguageCard(); + } + + dynamic_cast(GetCardMgr().GetRef(m_lastSlotToSetMainMemLCFromSnapshot)).SetGlobalLCMemMode(); +} + +bool LanguageCardManager::SetLanguageCard(SS_CARDTYPE type) +{ + if (type == CT_Empty) + { + m_pLanguageCard = NULL; + return true; + } + + _ASSERT(GetLanguageCard() == NULL); + if (GetLanguageCard()) + return false; // Only support one language card + + switch (type) + { + case CT_LanguageCard: + m_pLanguageCard = LanguageCardSlot0::create(SLOT0); + break; + case CT_LanguageCardIIe: + m_pLanguageCard = LanguageCardUnit::create(SLOT0); + break; + case CT_Saturn128K: + m_pLanguageCard = new Saturn128K(SLOT0, Saturn128K::GetSaturnMemorySize()); + break; + default: + _ASSERT(0); + return false; + } + + return true; +} diff --git a/source/LanguageCard.h b/source/LanguageCard.h index bc2bb054..0dda088d 100644 --- a/source/LanguageCard.h +++ b/source/LanguageCard.h @@ -18,7 +18,6 @@ public: virtual void Reset(const bool powerCycle) {} virtual void Update(const ULONG nExecutedCycles) {} - virtual void InitializeIO(LPBYTE pCxRomPeripheral); virtual UINT GetActiveBank(void) { return 0; } // Always 0 as only 1x 16K bank virtual void SaveSnapshot(YamlSaveHelper& yamlSaveHelper) { } // A no-op for //e - called from CardManager::SaveSnapshot() @@ -109,3 +108,34 @@ private: UINT m_uSaturnActiveBank; // Saturn 128K Language Card Bank 0 .. 7 LPBYTE m_aSaturnBanks[kMaxSaturnBanks]; }; + +// +// Language Card manager +// + +class LanguageCardManager +{ +public: + LanguageCardManager(void) : + m_pLanguageCard(NULL), + m_lastSlotToSetMainMemLC(SLOT0), + m_lastSlotToSetMainMemLCFromSnapshot(SLOT0) + {} + ~LanguageCardManager(void) {} + + void Reset(const bool powerCycle = false); + + UINT GetLastSlotToSetMainMemLC(void) { return m_lastSlotToSetMainMemLC; } + void SetLastSlotToSetMainMemLC(UINT slot) { m_lastSlotToSetMainMemLC = slot; } + void SetLastSlotToSetMainMemLCFromSnapshot(UINT slot) { m_lastSlotToSetMainMemLCFromSnapshot = slot; } + + LanguageCardUnit* GetLanguageCard(void) { return m_pLanguageCard; } + bool SetLanguageCard(SS_CARDTYPE type); + + void SetMemModeFromSnapshot(void); + +private: + LanguageCardUnit* m_pLanguageCard; + UINT m_lastSlotToSetMainMemLC; + UINT m_lastSlotToSetMainMemLCFromSnapshot; +}; diff --git a/source/Memory.cpp b/source/Memory.cpp index 5239b97a..885c75e9 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -241,8 +241,6 @@ static LPBYTE RWpages[kMaxExMemoryBanks]; // pointers to RW memory banks static const UINT kNumAnnunciators = 4; static bool g_Annunciator[kNumAnnunciators] = {}; -static UINT g_lastSlotToSetMainMemLC = SLOT0; -static UINT g_lastSlotToSetMainMemLCFromSnapshot = SLOT0; BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); @@ -373,15 +371,15 @@ UINT GetRamWorksActiveBank(void) static BOOL GetLastRamWrite(void) { - if (GetCardMgr().GetLanguageCard()) - return GetCardMgr().GetLanguageCard()->GetLastRamWrite(); + if (GetCardMgr().GetLanguageCardMgr().GetLanguageCard()) + return GetCardMgr().GetLanguageCardMgr().GetLanguageCard()->GetLastRamWrite(); return 0; } static void SetLastRamWrite(BOOL count) { - if (GetCardMgr().GetLanguageCard()) - GetCardMgr().GetLanguageCard()->SetLastRamWrite(count); + if (GetCardMgr().GetLanguageCardMgr().GetLanguageCard()) + GetCardMgr().GetLanguageCardMgr().GetLanguageCard()->SetLastRamWrite(count); } // @@ -393,7 +391,7 @@ void SetMemMainLanguageCard(LPBYTE ptr, UINT slot, bool bMemMain /*=false*/) else g_pMemMainLanguageCard = ptr; - g_lastSlotToSetMainMemLC = slot; + GetCardMgr().GetLanguageCardMgr().SetLastSlotToSetMainMemLC(slot); } LPBYTE GetCxRomPeripheral(void) @@ -401,11 +399,6 @@ LPBYTE GetCxRomPeripheral(void) return pCxRomPeripheral; // Can be NULL if at MODE_LOGO } -UINT GetLastSlotToSetMainMemLC(void) -{ - return g_lastSlotToSetMainMemLC; -} - //============================================================================= static BYTE __stdcall IORead_C00x(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles) @@ -1147,26 +1140,7 @@ void MemResetPaging() // . MemReset() -> ResetPaging(TRUE) static void ResetPaging(BOOL initialize) { - SetLastRamWrite(0); - - if (IsApple2PlusOrClone(GetApple2Type()) && GetCardMgr().QuerySlot(SLOT0) == CT_Empty) - SetMemMode(0); - else - SetMemMode(LanguageCardUnit::kMemModeInitialState); - - // For power on: card's ctor will have set card's local memmode to LanguageCardUnit::kMemModeInitialState. - // For reset: II/II+ unaffected, so only for //e or above. - if (IsAppleIIeOrAbove(GetApple2Type())) - { - if (GetCardMgr().QuerySlot(SLOT0) != CT_Empty) // LC or Saturn - dynamic_cast(GetCardMgr().GetRef(SLOT0)).SetLCMemMode(GetMemMode() & MF_LANGCARD_MASK); - for (UINT i = SLOT1; i < NUM_SLOTS; i++) - { - if (GetCardMgr().QuerySlot(i) == CT_Saturn128K) - dynamic_cast(GetCardMgr().GetRef(i)).SetLCMemMode(GetMemMode() & MF_LANGCARD_MASK); - } - } - + GetCardMgr().GetLanguageCardMgr().Reset(initialize); UpdatePaging(initialize); } @@ -1802,15 +1776,7 @@ void MemInitializeFromSnapshot(void) // NB. Copied to /mem/ by UpdatePaging(TRUE) } - // If multiple "Language Cards" (eg. LC+Saturn or 2xSaturn) then setup via the last card that selected the 16KB LC bank. - // NB. Skip if not Saturn card (ie. a LC), since LC's are only in slot0 and in the ctor it has called SetMainMemLanguageCard() - if (GetCardMgr().QuerySlot(g_lastSlotToSetMainMemLCFromSnapshot) == CT_Saturn128K) - { - Saturn128K& saturn = dynamic_cast(GetCardMgr().GetRef(g_lastSlotToSetMainMemLCFromSnapshot)); - saturn.SetMemMainLanguageCard(); - } - - dynamic_cast(GetCardMgr().GetRef(g_lastSlotToSetMainMemLCFromSnapshot)).SetGlobalLCMemMode(); + GetCardMgr().GetLanguageCardMgr().SetMemModeFromSnapshot(); // Finally setup the paging tables MemUpdatePaging(TRUE); @@ -2328,7 +2294,7 @@ void MemSaveSnapshot(YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IOSELECT_INT, INTC8ROM ? 1 : 0); yamlSaveHelper.SaveUint(SS_YAML_KEY_EXPANSIONROMTYPE, (UINT) g_eExpansionRomType); yamlSaveHelper.SaveUint(SS_YAML_KEY_PERIPHERALROMSLOT, g_uPeripheralRomSlot); - yamlSaveHelper.SaveUint(SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC, g_lastSlotToSetMainMemLC); + yamlSaveHelper.SaveUint(SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC, GetCardMgr().GetLanguageCardMgr().GetLastSlotToSetMainMemLC()); for (UINT i=0; i= 9) { - g_lastSlotToSetMainMemLCFromSnapshot = yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC); + GetCardMgr().GetLanguageCardMgr().SetLastSlotToSetMainMemLCFromSnapshot(yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC)); } yamlLoadHelper.PopMap();