II+: Working with Saturns in s0 and s3, including save/load state

This commit is contained in:
tomcw 2024-03-03 21:36:30 +00:00
parent 40bf9cd2d3
commit 1efa629bed
8 changed files with 80 additions and 34 deletions

View File

@ -115,22 +115,28 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type)
case CT_Uthernet2:
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_Saturn128K:
_ASSERT(m_pLanguageCard == NULL);
if (m_pLanguageCard) break; // Only support one language card
m_slot[slot] = m_pLanguageCard = new Saturn128K(slot, Saturn128K::GetSaturnMemorySize());
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);
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());
}
else
{
m_slot[slot] = new Saturn128K(slot, Saturn128K::kMaxSaturnBanks);
}
break;
default:
_ASSERT(0);
@ -165,10 +171,14 @@ void CardManager::RemoveInternal(UINT slot)
m_pParallelPrinterCard = NULL;
break;
case CT_LanguageCard:
case CT_Saturn128K:
case CT_LanguageCardIIe:
_ASSERT(slot == SLOT0);
m_pLanguageCard = NULL;
break;
case CT_Saturn128K:
if (slot == SLOT0)
m_pLanguageCard = NULL;
break;
case CT_Z80:
m_pZ80Card = NULL;
break;

View File

@ -157,6 +157,18 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
lpNextArg = GetNextArg(lpNextArg);
g_cmdLine.szImageName_harddisk[SLOT7][HARDDISK_2] = lpCmdLine;
}
else if (strcmp(lpCmdLine, "-s0") == 0) // Language Card options for Apple II/II+
{
lpCmdLine = GetCurrArg(lpNextArg);
lpNextArg = GetNextArg(lpNextArg);
if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0)
g_cmdLine.uSaturnBanks = Saturn128K::kMaxSaturnBanks;
else if (strcmp(lpCmdLine, "saturn64") == 0)
g_cmdLine.uSaturnBanks = Saturn128K::kMaxSaturnBanks / 2;
else if (strcmp(lpCmdLine, "languagecard") == 0 || strcmp(lpCmdLine, "lc") == 0)
g_cmdLine.bSlot0LanguageCard = true;
}
else if (lpCmdLine[0] == '-' && lpCmdLine[1] == 's' && lpCmdLine[2] >= '1' && lpCmdLine[2] <= '7')
{
const UINT slot = lpCmdLine[2] - '0';
@ -176,6 +188,8 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
}
if (strcmp(lpCmdLine, "hdc") == 0)
g_cmdLine.slotInsert[slot] = CT_GenericHDD;
if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0) // Support Saturn128 card in slot 1-7 too (GH#1279)
g_cmdLine.slotInsert[slot] = CT_Saturn128K;
if (strcmp(lpCmdLine, "megaaudio") == 0)
{
g_cmdLine.slotInsert[slot] = CT_MegaAudio;
@ -343,18 +357,6 @@ bool ProcessCmdLine(LPSTR lpCmdLine)
g_cmdLine.uRamWorksExPages = 1;
}
#endif
else if (strcmp(lpCmdLine, "-s0") == 0)
{
lpCmdLine = GetCurrArg(lpNextArg);
lpNextArg = GetNextArg(lpNextArg);
if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0)
g_cmdLine.uSaturnBanks = Saturn128K::kMaxSaturnBanks;
else if (strcmp(lpCmdLine, "saturn64") == 0)
g_cmdLine.uSaturnBanks = Saturn128K::kMaxSaturnBanks/2;
else if (strcmp(lpCmdLine, "languagecard") == 0 || strcmp(lpCmdLine, "lc") == 0)
g_cmdLine.bSlot0LanguageCard = true;
}
else if (strcmp(lpCmdLine, "-f8rom") == 0) // Use custom 2K ROM at [$F800..$FFFF]
{
lpCmdLine = GetCurrArg(lpNextArg);

View File

@ -47,15 +47,17 @@ LanguageCardUnit::LanguageCardUnit(SS_CARDTYPE type, UINT slot) :
Card(type, slot),
m_uLastRamWrite(0)
{
if (m_slot != LanguageCardUnit::kSlot0)
if (type != CT_Saturn128K && m_slot != LanguageCardUnit::kSlot0)
ThrowErrorInvalidSlot();
SetMemMainLanguageCard(NULL, true);
if (m_slot == SLOT0)
SetMemMainLanguageCard(NULL, SLOT0, true);
}
LanguageCardUnit::~LanguageCardUnit(void)
{
SetMemMainLanguageCard(NULL);
if (m_slot == SLOT0)
SetMemMainLanguageCard(NULL, SLOT0);
}
void LanguageCardUnit::InitializeIO(LPBYTE pCxRomPeripheral)
@ -154,7 +156,8 @@ LanguageCardSlot0::LanguageCardSlot0(SS_CARDTYPE type, UINT slot)
: LanguageCardUnit(type, slot)
{
m_pMemory = new BYTE[kMemBankSize];
SetMemMainLanguageCard(m_pMemory);
if (m_slot == SLOT0)
SetMemMainLanguageCard(m_pMemory, SLOT0);
}
LanguageCardSlot0::~LanguageCardSlot0(void)
@ -261,7 +264,8 @@ Saturn128K::Saturn128K(UINT slot, UINT banks)
for (UINT i = 1; i < m_uSaturnTotalBanks; i++)
m_aSaturnBanks[i] = new BYTE[kMemBankSize]; // Saturn banks are 16K, max 8 banks/card
SetMemMainLanguageCard( m_aSaturnBanks[ m_uSaturnActiveBank ] );
if (slot == SLOT0)
SetMemMainLanguageCard(m_aSaturnBanks[m_uSaturnActiveBank], SLOT0);
}
Saturn128K::~Saturn128K(void)
@ -334,7 +338,7 @@ BYTE __stdcall Saturn128K::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULO
pLC->m_uSaturnActiveBank = pLC->m_uSaturnTotalBanks-1; // FIXME: just prevent crash for now!
}
SetMemMainLanguageCard( pLC->m_aSaturnBanks[ pLC->m_uSaturnActiveBank ] );
SetMemMainLanguageCard(pLC->m_aSaturnBanks[pLC->m_uSaturnActiveBank], uSlot);
bBankChanged = true;
}
else
@ -453,13 +457,18 @@ bool Saturn128K::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version)
yamlLoadHelper.PopMap();
}
SetMemMainLanguageCard( m_aSaturnBanks[ m_uSaturnActiveBank ] );
// NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2()
// NB. MemInitializeFromSnapshot() called at end of Snapshot_LoadState_v2():
// . SetMemMainLanguageCard() for the slot/card that last set the 16KB LC bank
// . MemUpdatePaging(TRUE)
return true;
}
void Saturn128K::SetMainMemLanguageCard(void)
{
SetMemMainLanguageCard(m_aSaturnBanks[m_uSaturnActiveBank], m_slot);
}
void Saturn128K::SetSaturnMemorySize(UINT banks)
{
g_uSaturnBanksFromCmdLine = banks;

View File

@ -85,6 +85,8 @@ public:
virtual void SaveSnapshot(YamlSaveHelper& yamlSaveHelper);
virtual bool LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT version);
void SetMainMemLanguageCard(void);
static UINT GetSaturnMemorySize();
static void SetSaturnMemorySize(UINT banks);

View File

@ -241,6 +241,8 @@ 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);
@ -384,12 +386,14 @@ static void SetLastRamWrite(BOOL count)
//
void SetMemMainLanguageCard(LPBYTE ptr, bool bMemMain /*=false*/)
void SetMemMainLanguageCard(LPBYTE ptr, UINT slot, bool bMemMain /*=false*/)
{
if (bMemMain)
g_pMemMainLanguageCard = memmain+0xC000;
else
g_pMemMainLanguageCard = ptr;
g_lastSlotToSetMainMemLC = slot;
}
LPBYTE GetCxRomPeripheral(void)
@ -1777,6 +1781,15 @@ 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.SetMainMemLanguageCard();
}
// Finally setup the paging tables
MemUpdatePaging(TRUE);
//
@ -2208,6 +2221,7 @@ void MemRemoveNoSlotClock(void)
#define SS_YAML_KEY_EXPANSIONROMTYPE "Expansion ROM Type"
#define SS_YAML_KEY_PERIPHERALROMSLOT "Peripheral ROM Slot"
#define SS_YAML_KEY_ANNUNCIATOR "Annunciator"
#define SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC "Last Slot to Set Main Mem LC"
//
@ -2282,6 +2296,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);
for (UINT i=0; i<kNumAnnunciators; i++)
{
@ -2343,6 +2358,12 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT unitVersion)
}
}
g_lastSlotToSetMainMemLCFromSnapshot = SLOT0;
if (unitVersion >= 9)
{
g_lastSlotToSetMainMemLCFromSnapshot = yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTSLOTTOSETMAINMEMLC);
}
yamlLoadHelper.PopMap();
//

View File

@ -115,6 +115,6 @@ SS_CARDTYPE GetCurrentExpansionMemType(void);
void SetRamWorksMemorySize(UINT pages);
UINT GetRamWorksActiveBank(void);
void SetMemMainLanguageCard(LPBYTE ptr, bool bMemMain=false);
void SetMemMainLanguageCard(LPBYTE ptr, UINT slot, bool bMemMain=false);
LPBYTE GetCxRomPeripheral(void);

View File

@ -67,7 +67,8 @@ static YamlHelper yamlHelper;
// v6: Added 'Unit Miscellaneous' for NoSlotClock(NSC)
// v7: Extended: joystick (added 'Paddle Inactive Cycle')
// v8: Added 'Unit Game I/O Connector' for Game I/O Connector
#define UNIT_APPLE2_VER 8
// v9: Extended: memory (added 'Last Slot to Set Main Mem LC')
#define UNIT_APPLE2_VER 9
#define UNIT_SLOTS_VER 1
@ -292,7 +293,7 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT unitVersion)
SS_CARDTYPE type = Card::GetCardType(card);
bool bRes = false;
if (slot == 0)
if (slot == SLOT0)
{
SetExpansionMemType(type); // calls GetCardMgr().Insert() & InsertAux()
}

View File

@ -770,9 +770,10 @@ static void RepeatInitialization(void)
GetCardMgr().GetParallelPrinterCard()->SetEnableDumpToRealPrinter(true);
}
if (g_cmdLine.slotInsert[SLOT3] != CT_Empty && g_cmdLine.slotInsert[SLOT3] == CT_VidHD) // For now just support VidHD in slot 3
if (g_cmdLine.slotInsert[SLOT3] != CT_Empty)
{
GetCardMgr().Insert(SLOT3, g_cmdLine.slotInsert[SLOT3]);
if (g_cmdLine.slotInsert[SLOT3] == CT_VidHD || g_cmdLine.slotInsert[SLOT3] == CT_Saturn128K) // For now just support VidHD and Saturn128 in slot 3)
GetCardMgr().Insert(SLOT3, g_cmdLine.slotInsert[SLOT3]);
}
if (g_cmdLine.slotInsert[SLOT4] != CT_Empty)