Add LanguageCardManager class

This commit is contained in:
tomcw 2024-03-22 21:04:53 +00:00
parent 37c031c193
commit 729cd56093
6 changed files with 132 additions and 69 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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)
{

View File

@ -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<LanguageCardUnit&>(GetCardMgr().GetRef(SLOT0)).SetLCMemMode(GetMemMode() & MF_LANGCARD_MASK);
for (UINT i = SLOT1; i < NUM_SLOTS; i++)
{
if (GetCardMgr().QuerySlot(i) == CT_Saturn128K)
dynamic_cast<LanguageCardUnit&>(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<Saturn128K&>(GetCardMgr().GetRef(m_lastSlotToSetMainMemLCFromSnapshot));
saturn.SetMemMainLanguageCard();
}
dynamic_cast<LanguageCardUnit&>(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;
}

View File

@ -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;
};

View File

@ -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<LanguageCardUnit&>(GetCardMgr().GetRef(SLOT0)).SetLCMemMode(GetMemMode() & MF_LANGCARD_MASK);
for (UINT i = SLOT1; i < NUM_SLOTS; i++)
{
if (GetCardMgr().QuerySlot(i) == CT_Saturn128K)
dynamic_cast<LanguageCardUnit&>(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<Saturn128K&>(GetCardMgr().GetRef(g_lastSlotToSetMainMemLCFromSnapshot));
saturn.SetMemMainLanguageCard();
}
dynamic_cast<LanguageCardUnit&>(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<kNumAnnunciators; i++)
{
@ -2399,10 +2365,10 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT unitVersion)
}
}
g_lastSlotToSetMainMemLCFromSnapshot = SLOT0;
GetCardMgr().GetLanguageCardMgr().SetLastSlotToSetMainMemLCFromSnapshot(SLOT0);
if (unitVersion >= 9)
{
g_lastSlotToSetMainMemLCFromSnapshot = yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC);
GetCardMgr().GetLanguageCardMgr().SetLastSlotToSetMainMemLCFromSnapshot(yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC));
}
yamlLoadHelper.PopMap();