diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 5dddcdf8..cb01a4b1 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -1142,6 +1142,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) bool bSetFullScreen = false; bool bBoot = false; bool bChangedDisplayResolution = false; + bool bSlot0LanguageCard = false; bool bSlot7Empty = false; UINT bestWidth = 0, bestHeight = 0; LPSTR szImageName_drive[NUM_DRIVES] = {NULL,NULL}; @@ -1269,11 +1270,12 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); - // "The boards consist of 16K banks of memory (4 banks for the 64K board, 8 banks for the 128K), accessed one at a time" - Ref: "64K/128K RAM BOARD", Saturn Systems, Ch.1 Introduction(pg-5) if (strcmp(lpCmdLine, "saturn") == 0 || strcmp(lpCmdLine, "saturn128") == 0) uSaturnBanks = Saturn128K::kMaxSaturnBanks; else if (strcmp(lpCmdLine, "saturn64") == 0) uSaturnBanks = Saturn128K::kMaxSaturnBanks/2; + else if (strcmp(lpCmdLine, "languagecard") == 0 || strcmp(lpCmdLine, "lc") == 0) + bSlot0LanguageCard = true; } else if (strcmp(lpCmdLine, "-f8rom") == 0) // Use custom 2K ROM at [$F800..$FFFF] { @@ -1470,6 +1472,12 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) uSaturnBanks = 0; // Don't reapply after a restart } + if (bSlot0LanguageCard) + { + SetExpansionMemType(CT_LanguageCard); + bSlot0LanguageCard = false; // Don't reapply after a restart + } + DebugInitialize(); LogFileOutput("Main: DebugInitialize()\n"); diff --git a/source/Common.h b/source/Common.h index 0bdfa9e4..c8572e96 100644 --- a/source/Common.h +++ b/source/Common.h @@ -193,6 +193,11 @@ enum eApple2Type { A2TYPE_MAX }; +inline bool IsApple2Original(eApple2Type type) // Apple ][ +{ + return type == A2TYPE_APPLE2; +} + inline bool IsApple2Plus(eApple2Type type) // Apple ][,][+ { return (type & (APPLE2E_MASK|APPLE2C_MASK)) == 0; diff --git a/source/LanguageCard.cpp b/source/LanguageCard.cpp index 44c6413f..2c61139c 100644 --- a/source/LanguageCard.cpp +++ b/source/LanguageCard.cpp @@ -44,6 +44,11 @@ LanguageCardUnit::LanguageCardUnit(void) : SetMemMainLanguageCard(NULL, true); } +LanguageCardUnit::~LanguageCardUnit(void) +{ + SetMemMainLanguageCard(NULL); +} + DWORD LanguageCardUnit::SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write) { memmode &= ~(MF_BANK2 | MF_HIGHRAM); diff --git a/source/LanguageCard.h b/source/LanguageCard.h index c3654dfe..7134b1d5 100644 --- a/source/LanguageCard.h +++ b/source/LanguageCard.h @@ -8,7 +8,7 @@ class LanguageCardUnit { public: LanguageCardUnit(void); - virtual ~LanguageCardUnit(void) {} + virtual ~LanguageCardUnit(void); virtual DWORD SetPaging(WORD address, DWORD memmode, BOOL& modechanging, bool write); virtual void SetMemorySize(UINT banks) {} // No-op for //e and slot-0 16K LC @@ -71,6 +71,7 @@ public: virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); virtual bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); + // "The boards consist of 16K banks of memory (4 banks for the 64K board, 8 banks for the 128K), accessed one at a time" - Ref: "64K/128K RAM BOARD", Saturn Systems, Ch.1 Introduction(pg-5) static const UINT kMaxSaturnBanks = 8; // 8 * 16K = 128K static std::string GetSnapshotCardName(void); diff --git a/source/Memory.cpp b/source/Memory.cpp index 3996bee5..52efdbe1 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -214,6 +214,9 @@ BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYT //============================================================================= +// Default memory types on a VM restart +// - can be overwritten by cmd-line or loading a save-state +static SS_CARDTYPE g_MemTypeAppleII = CT_Empty; static SS_CARDTYPE g_MemTypeAppleIIPlus = CT_LanguageCard; // Keep a copy so it's not lost if machine type changes, eg: A][ -> A//e -> A][ static SS_CARDTYPE g_MemTypeAppleIIe = CT_Extended80Col; // Keep a copy so it's not lost if machine type changes, eg: A//e -> A][ -> A//e static UINT g_uSaturnBanksFromCmdLine = 0; @@ -221,14 +224,18 @@ static UINT g_uSaturnBanksFromCmdLine = 0; // Called from MemLoadSnapshot() static void ResetDefaultMachineMemTypes(void) { + g_MemTypeAppleII = CT_Empty; g_MemTypeAppleIIPlus = CT_LanguageCard; g_MemTypeAppleIIe = CT_Extended80Col; } // Called from MemInitialize(), MemLoadSnapshot() -void SetExpansionMemTypeDefault(void) +static void SetExpansionMemTypeDefault(void) { - SS_CARDTYPE defaultType = IsApple2PlusOrClone(GetApple2Type()) ? g_MemTypeAppleIIPlus : g_MemTypeAppleIIe; + SS_CARDTYPE defaultType = IsApple2Original(GetApple2Type()) ? g_MemTypeAppleII + : IsApple2PlusOrClone(GetApple2Type()) ? g_MemTypeAppleIIPlus + : g_MemTypeAppleIIe; + SetExpansionMemType(defaultType); } @@ -239,7 +246,12 @@ void SetExpansionMemType(const SS_CARDTYPE type) SS_CARDTYPE newSlotAuxCard; // Set defaults: - if (IsApple2PlusOrClone(GetApple2Type())) + if (IsApple2Original(GetApple2Type())) + { + newSlot0Card = CT_Empty; + newSlotAuxCard = CT_Empty; + } + else if (IsApple2PlusOrClone(GetApple2Type())) { newSlot0Card = CT_LanguageCard; newSlotAuxCard = CT_Empty; @@ -250,11 +262,12 @@ void SetExpansionMemType(const SS_CARDTYPE type) newSlotAuxCard = CT_Extended80Col; } - if (type == CT_Saturn128K) + if (type == CT_LanguageCard || type == CT_Saturn128K) { + g_MemTypeAppleII = type; g_MemTypeAppleIIPlus = type; if (IsApple2PlusOrClone(GetApple2Type())) - newSlot0Card = CT_Saturn128K; + newSlot0Card = type; else newSlot0Card = CT_Empty; // NB. No slot0 for //e } @@ -264,18 +277,19 @@ void SetExpansionMemType(const SS_CARDTYPE type) if (IsApple2PlusOrClone(GetApple2Type())) newSlotAuxCard = CT_Empty; // NB. No aux slot for ][ or ][+ else - newSlotAuxCard = CT_RamWorksIII; + newSlotAuxCard = type; } if (IsApple2PlusOrClone(GetApple2Type())) { delete g_pLanguageCard; - g_pLanguageCard = NULL; if (newSlot0Card == CT_Saturn128K) g_pLanguageCard = new Saturn128K(g_uSaturnBanksFromCmdLine); - else // newSlot0Card == CT_LanguageCard + else if (newSlot0Card == CT_LanguageCard) g_pLanguageCard = new LanguageCardSlot0; + else + g_pLanguageCard = NULL; } else { @@ -283,8 +297,6 @@ void SetExpansionMemType(const SS_CARDTYPE type) g_pLanguageCard = new LanguageCardUnit; } - _ASSERT(g_pMemMainLanguageCard); - g_Slot0 = newSlot0Card; g_SlotAux = newSlotAuxCard; } @@ -318,12 +330,15 @@ void SetSaturnMemorySize(UINT banks) static BOOL GetLastRamWrite(void) { - return g_pLanguageCard->GetLastRamWrite(); + if (g_pLanguageCard) + return g_pLanguageCard->GetLastRamWrite(); + return 0; } static void SetLastRamWrite(BOOL count) { - g_pLanguageCard->SetLastRamWrite(count); + if (g_pLanguageCard) + g_pLanguageCard->SetLastRamWrite(count); } // @@ -338,6 +353,7 @@ void SetMemMainLanguageCard(LPBYTE ptr, bool bMemMain /*=false*/) LanguageCardUnit* GetLanguageCard(void) { + _ASSERT(g_pLanguageCard); return g_pLanguageCard; } @@ -1003,7 +1019,12 @@ void MemResetPaging() static void ResetPaging(BOOL initialize) { SetLastRamWrite(0); - SetMemMode(LanguageCardUnit::kMemModeInitialState); + + if (IsApple2PlusOrClone(GetApple2Type()) && g_Slot0 == CT_Empty) + SetMemMode(0); + else + SetMemMode(LanguageCardUnit::kMemModeInitialState); + UpdatePaging(initialize); } @@ -1178,8 +1199,6 @@ void MemDestroy() mem = NULL; - g_pMemMainLanguageCard = NULL; - ZeroMemory(memwrite, sizeof(memwrite)); ZeroMemory(memshadow,sizeof(memshadow)); } @@ -1519,6 +1538,36 @@ void MemInitializeROM(void) void MemInitializeCustomF8ROM(void) { const UINT F8RomSize = 0x800; + const UINT F8RomOffset = Apple2RomSize-F8RomSize; + + if (IsApple2Original(GetApple2Type()) && g_Slot0 == CT_LanguageCard) + { + try + { + HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2_PLUS_ROM), "ROM"); + if (hResInfo == NULL) + throw false; + + DWORD dwResSize = SizeofResource(NULL, hResInfo); + if(dwResSize != Apple2RomSize) + throw false; + + HGLOBAL hResData = LoadResource(NULL, hResInfo); + if(hResData == NULL) + throw false; + + BYTE* pData = (BYTE*) LockResource(hResData); // NB. Don't need to unlock resource + if (pData == NULL) + throw false; + + memcpy(memrom+F8RomOffset, pData+F8RomOffset, F8RomSize); + } + catch (bool) + { + MessageBox( g_hFrameWindow, "Failed to read F8 (auto-start) ROM for language card in original Apple][", TEXT("AppleWin Error"), MB_OK ); + } + } + if (g_hCustomRomF8 != INVALID_HANDLE_VALUE) { BYTE OldRom[Apple2RomSize]; // NB. 12KB on stack @@ -1526,7 +1575,7 @@ void MemInitializeCustomF8ROM(void) SetFilePointer(g_hCustomRomF8, 0, NULL, FILE_BEGIN); DWORD uNumBytesRead; - BOOL bRes = ReadFile(g_hCustomRomF8, memrom+Apple2RomSize-F8RomSize, F8RomSize, &uNumBytesRead, NULL); + BOOL bRes = ReadFile(g_hCustomRomF8, memrom+F8RomOffset, F8RomSize, &uNumBytesRead, NULL); if (uNumBytesRead != F8RomSize) { memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF @@ -1854,7 +1903,7 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE #endif // DETERMINE THE NEW MEMORY PAGING MODE. - if ((address >= 0x80) && (address <= 0x8F)) + if (g_Slot0 != CT_Empty && (address >= 0x80 && address <= 0x8F)) { SetMemMode( g_pLanguageCard->SetPaging(address, memmode, modechanging, write ? true : false) ); } diff --git a/source/SaveState.cpp b/source/SaveState.cpp index e7c36fad..c61cabf5 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -605,7 +605,7 @@ void Snapshot_SaveState(void) yamlSaveHelper.UnitHdr(GetSnapshotUnitSlotsName(), UNIT_SLOTS_VER); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - if (IsApple2PlusOrClone(GetApple2Type())) + if (g_Slot0 != CT_Empty && IsApple2PlusOrClone(GetApple2Type())) GetLanguageCard()->SaveSnapshot(yamlSaveHelper); // Language Card or Saturn 128K Printer_SaveSnapshot(yamlSaveHelper);