diff --git a/help/CommandLine.html b/help/CommandLine.html index a1f9c972..f73f7e26 100644 --- a/help/CommandLine.html +++ b/help/CommandLine.html @@ -87,8 +87,12 @@ Set the number of blocks returned by a ProDOS status call. Use -harddisknumblocks 32767 to have the same autoexpanding behavior as older AppleWin versions.

-no-nsc
Remove the No-Slot clock (NSC).

- -r <number of pages>
- Emulate a RamWorks III card with 1 to 127 pages (each page is 64K, giving a max of 8MB) in the auxiliary slot in an Apple //e machine.

+ -aux <empty|std80|ext80|rw3>
+ Remove ('empty') or insert 80-Column('std80'), Extended 80-Column('ext80') or RamWorks III('rw3') card into auxiliary slot in Apple //e.
+ NB. 'rw3' will default to 8128KiB (127 banks of 64K) unless overriden by -r switch.

+ -r <number of banks>
+ Emulate a RamWorks III card with 1 to 256 banks (each bank is 64K, giving a max of 16MB) in the auxiliary slot in an Apple //e machine.
+ (Implicitly inserts a RamWorks III card into the aux slot.)

-load-state <savestate>
Load a save-state file (and auto power-on the Apple II).
NB. This takes precedent over the -d1, -d2, -s#d#, -h1, -h2, s0-7, -model and -r switches.

diff --git a/source/CardManager.cpp b/source/CardManager.cpp index f32eddae..9f86492a 100644 --- a/source/CardManager.cpp +++ b/source/CardManager.cpp @@ -219,10 +219,17 @@ void CardManager::InsertAuxInternal(SS_CARDTYPE type) RemoveAux(); // creates a new EmptyCard } -void CardManager::InsertAux(SS_CARDTYPE type) +void CardManager::InsertAux(SS_CARDTYPE type, bool updateRegistry/*=true*/) { InsertAuxInternal(type); - RegSetConfigSlotNewCardType(SLOT_AUX, type); + if (updateRegistry) + { + if (type != CT_RamWorksIII) + SetRamWorksMemorySize(1, false); // 1x 64K bank for Empty/80Col/Extended80Col cards + + RegSetConfigSlotNewCardType(SLOT_AUX, type); + SetRegistryAuxNumberOfBanks(); + } } void CardManager::RemoveAuxInternal() diff --git a/source/CardManager.h b/source/CardManager.h index 03e8591f..180116be 100644 --- a/source/CardManager.h +++ b/source/CardManager.h @@ -45,7 +45,7 @@ public: return m_slot[slot]; } - void InsertAux(SS_CARDTYPE type); + void InsertAux(SS_CARDTYPE type, bool updateRegistry = true); void RemoveAux(void); SS_CARDTYPE QueryAux(void) { return m_aux->QueryType(); } Card* GetObjAux(void) { _ASSERT(0); return m_aux; } // ASSERT because this is a DummyCard diff --git a/source/CmdLine.cpp b/source/CmdLine.cpp index 52bf589b..bf5f7c36 100644 --- a/source/CmdLine.cpp +++ b/source/CmdLine.cpp @@ -316,6 +316,8 @@ bool ProcessCmdLine(LPSTR lpCmdLine) else if (strcmp(lpCmdLine, "rw3") == 0) { g_cmdLine.auxSlotInsert = CT_RamWorksIII; + if (!g_cmdLine.uRamWorksExPages) + g_cmdLine.uRamWorksExPages = kMaxExMemoryBanksRealRW3; // default to ~8MB (ie. the max for the real RW3 card) } else { @@ -410,16 +412,16 @@ bool ProcessCmdLine(LPSTR lpCmdLine) g_nMemoryClearType = NUM_MIP - 1; } #ifdef RAMWORKS - else if (strcmp(lpCmdLine, "-r") == 0) // RamWorks size [1..127] + else if (strcmp(lpCmdLine, "-r") == 0) // RamWorks size [1..256] { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_cmdLine.uRamWorksExPages = atoi(lpCmdLine); if (g_cmdLine.uRamWorksExPages > kMaxExMemoryBanks) g_cmdLine.uRamWorksExPages = kMaxExMemoryBanks; - else - if (g_cmdLine.uRamWorksExPages < 1) - g_cmdLine.uRamWorksExPages = 1; + else if (g_cmdLine.uRamWorksExPages < 1) + g_cmdLine.uRamWorksExPages = 1; // 1x64KB (aux mem) + g_cmdLine.auxSlotInsert = CT_RamWorksIII; // Insert RW3 into aux slot } #endif else if (strcmp(lpCmdLine, "-f8rom") == 0) // Use custom 2K ROM at [$F800..$FFFF] diff --git a/source/Common.h b/source/Common.h index 9c6d713d..426e683c 100644 --- a/source/Common.h +++ b/source/Common.h @@ -114,6 +114,7 @@ enum AppMode_e #define REGVALUE_SLOT4 "Slot 4" // GH#977: Deprecated from 1.30.4 #define REGVALUE_SLOT5 "Slot 5" // GH#977: Deprecated from 1.30.4 #define REGVALUE_VERSION "Version" +#define REGVALUE_AUX_NUM_BANKS "Number of Banks" #define REG_CONFIG_SLOT_AUX "Slot Auxiliary" #define REG_CONFIG_SLOT "Slot " #define REGVALUE_CARD_TYPE "Card type" diff --git a/source/Memory.cpp b/source/Memory.cpp index 165db789..d8638fe1 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -43,6 +43,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "NTSC.h" #include "NoSlotClock.h" #include "Pravets.h" +#include "Registry.h" #include "Speaker.h" #include "Tape.h" #include "RGBMonitor.h" @@ -258,8 +259,8 @@ LPBYTE memVidHD = NULL; // For Apple II/II+ writes to aux mem (on VidHD card). static CNoSlotClock* g_NoSlotClock = new CNoSlotClock; #ifdef RAMWORKS -static UINT g_uMaxExPages = 1; // user requested ram pages (default to 1 aux bank: so total = 128KB) -static UINT g_uActiveBank = 0; // 0 = aux 64K for: //e extended 80 Col card, or //c -- ALSO RAMWORKS +static UINT g_uMaxExBanks = 1; // user requested ram banks (default to 1 aux bank: so total = 128KB) +static UINT g_uActiveBank = 0; // 0 = aux 64K for: //e extended 80 Col card, or //c -- also RamWorks III aux card static LPBYTE RWpages[kMaxExMemoryBanks]; // pointers to RW memory banks #endif @@ -312,7 +313,7 @@ static void SetExpansionMemTypeDefault(void) } // Called from SetExpansionMemTypeDefault(), MemLoadSnapshotAux(), SaveState.cpp_ParseSlots(), cmd-line switch -void SetExpansionMemType(const SS_CARDTYPE type) +void SetExpansionMemType(const SS_CARDTYPE type, bool updateRegistry/*=true*/) { SS_CARDTYPE newSlot0Card; SS_CARDTYPE newSlotAuxCard; @@ -367,7 +368,7 @@ void SetExpansionMemType(const SS_CARDTYPE type) } GetCardMgr().Insert(SLOT0, newSlot0Card); - GetCardMgr().InsertAux(newSlotAuxCard); + GetCardMgr().InsertAux(newSlotAuxCard, updateRegistry); } void CreateLanguageCard(void) @@ -403,9 +404,22 @@ SS_CARDTYPE GetCurrentExpansionMemType(void) // -void SetRamWorksMemorySize(UINT pages) +void SetRamWorksMemorySize(UINT banks, bool updateRegistry/*=true*/) { - g_uMaxExPages = pages; + _ASSERT(banks <= kMaxExMemoryBanks); + if (banks > kMaxExMemoryBanks) + banks = kMaxExMemoryBanks; + + g_uMaxExBanks = banks; + + if (updateRegistry) + SetRegistryAuxNumberOfBanks(); +} + +void SetRegistryAuxNumberOfBanks(void) +{ + std::string regSection = RegGetConfigSlotSection(SLOT_AUX); + RegSaveValue(regSection.c_str(), REGVALUE_AUX_NUM_BANKS, TRUE, g_uMaxExBanks); } UINT GetRamWorksActiveBank(void) @@ -1616,7 +1630,7 @@ LPBYTE MemGetBankPtr(const UINT nBank, const bool isSaveSnapshotOrDebugging/*=tr BackMainImage(); // Flush any dirty pages to back-buffer #ifdef RAMWORKS - if (nBank > g_uMaxExPages) + if (nBank > g_uMaxExBanks) return NULL; if (nBank == 0) @@ -1849,11 +1863,11 @@ void MemInitialize() #ifdef RAMWORKS if (GetCardMgr().QueryAux() == CT_RamWorksIII) { - // allocate memory for RAMWorks III - up to 8MB + // allocate memory for RamWorks III - up to 16MB g_uActiveBank = 0; UINT i = 1; - while ((i < g_uMaxExPages) && (RWpages[i] = ALIGNED_ALLOC(_6502_MEM_LEN))) + while ((i < g_uMaxExBanks) && (RWpages[i] = ALIGNED_ALLOC(_6502_MEM_LEN))) i++; while (i < kMaxExMemoryBanks) RWpages[i++] = NULL; @@ -2377,7 +2391,7 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE #ifdef RAMWORKS case 0x71: // extended memory aux page number case 0x73: // Ramworks III set aux page number - if ((value < g_uMaxExPages) && RWpages[value]) + if ((value < g_uMaxExBanks) && RWpages[value]) { g_uActiveBank = value; memaux = RWpages[g_uActiveBank]; @@ -2775,7 +2789,7 @@ void MemSaveSnapshotAux(YamlSaveHelper& yamlSaveHelper) if (IS_APPLE2C()) { - _ASSERT(g_uMaxExPages == 1); + _ASSERT(g_uMaxExBanks == 1); } yamlSaveHelper.UnitHdr(MemGetSnapshotUnitAuxSlotName(), kUNIT_AUXSLOT_VER); @@ -2812,10 +2826,10 @@ void MemSaveSnapshotAux(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label cardState(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - yamlSaveHelper.Save("%s: 0x%02X # [0,1..7F] 0=no aux mem, 1=128K system, etc\n", SS_YAML_KEY_NUMAUXBANKS, g_uMaxExPages); - yamlSaveHelper.Save("%s: 0x%02X # [ 0..7E] 0=memaux\n", SS_YAML_KEY_ACTIVEAUXBANK, g_uActiveBank); + yamlSaveHelper.Save("%s: 0x%03X # [0,1..100] 0=no aux mem, 1=128K system, etc\n", SS_YAML_KEY_NUMAUXBANKS, g_uMaxExBanks); + yamlSaveHelper.Save("%s: 0x%02X # [ 0..FF] 0=memaux\n", SS_YAML_KEY_ACTIVEAUXBANK, g_uActiveBank); - for(UINT bank = 1; bank <= g_uMaxExPages; bank++) + for(UINT bank = 1; bank <= g_uMaxExBanks; bank++) { MemSaveSnapshotMemory(yamlSaveHelper, false, bank); } @@ -2827,7 +2841,7 @@ void MemSaveSnapshotAux(YamlSaveHelper& yamlSaveHelper) static SS_CARDTYPE MemLoadSnapshotAuxCommon(YamlLoadHelper& yamlLoadHelper, const std::string& card) { - g_uMaxExPages = 1; // Must be at least 1 (for aux mem) - regardless of Apple2 type! + g_uMaxExBanks = 1; // Must be at least 1 (for aux mem) - regardless of Apple2 type! g_uActiveBank = 0; _ASSERT(MemGetBankPtr(1, false)); // Ensure there is always aux mem (eg. for CT_80Col or CT_VidHD) @@ -2878,16 +2892,16 @@ static SS_CARDTYPE MemLoadSnapshotAuxCommon(YamlLoadHelper& yamlLoadHelper, cons } else // cardType == CT_RamWorksIII { - if (numAuxBanks < 2 || numAuxBanks > 0x7F || (activeAuxBank + 1) > numAuxBanks) + if (numAuxBanks < 2 || numAuxBanks > kMaxExMemoryBanks || (activeAuxBank + 1) > numAuxBanks) throw std::runtime_error(SS_YAML_KEY_UNIT ": AuxSlot: Bad aux slot card state"); } - g_uMaxExPages = numAuxBanks; + g_uMaxExBanks = numAuxBanks; g_uActiveBank = activeAuxBank; // - for (UINT bank = 1; bank <= g_uMaxExPages; bank++) + for (UINT bank = 1; bank <= g_uMaxExBanks; bank++) { LPBYTE pBank = MemGetBankPtr(bank, false); if (!pBank) diff --git a/source/Memory.h b/source/Memory.h index ad3cde1c..f5ce607a 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -51,7 +51,8 @@ extern LPBYTE memdirty; extern LPBYTE memVidHD; #ifdef RAMWORKS -const UINT kMaxExMemoryBanks = 127; // 127 * aux mem(64K) + main mem(64K) = 8MB +const UINT kMaxExMemoryBanks = 256; // 256 * aux mem(64K) + main mem(64K) = 16MB + 64K +const UINT kMaxExMemoryBanksRealRW3 = 127; // Real RW3 was limited to 127x64MB, so ~8MB in total #endif void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, iofunction IOReadCx, iofunction IOWriteCx, LPVOID lpSlotParameter, BYTE* pExpansionRom); @@ -103,11 +104,12 @@ BYTE __stdcall MemSetPaging(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExec BYTE __stdcall IO_F8xx(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); -void SetExpansionMemType(const SS_CARDTYPE type); +void SetExpansionMemType(const SS_CARDTYPE type, bool updateRegistry=true); SS_CARDTYPE GetCurrentExpansionMemType(void); -void SetRamWorksMemorySize(UINT pages); +void SetRamWorksMemorySize(UINT banks, bool updateRegistry=true); UINT GetRamWorksActiveBank(void); void SetMemMainLanguageCard(LPBYTE ptr, UINT slot, bool bMemMain=false); +void SetRegistryAuxNumberOfBanks(void); LPBYTE GetCxRomPeripheral(void); diff --git a/source/Utilities.cpp b/source/Utilities.cpp index 64a61899..1781643a 100644 --- a/source/Utilities.cpp +++ b/source/Utilities.cpp @@ -269,6 +269,23 @@ void LoadConfiguration(bool loadImages) } } + // Aux slot + + { + std::string regSection = RegGetConfigSlotSection(SLOT_AUX); + + if (RegLoadValue(regSection.c_str(), REGVALUE_CARD_TYPE, TRUE, &dwTmp)) + { + SS_CARDTYPE type = (SS_CARDTYPE)dwTmp; + const bool noUpdateRegistry = false; + GetCardMgr().InsertAux(type, noUpdateRegistry); + SetExpansionMemType(type, noUpdateRegistry); + + RegLoadValue(regSection.c_str(), REGVALUE_AUX_NUM_BANKS, TRUE, &dwTmp, kMaxExMemoryBanksRealRW3); + SetRamWorksMemorySize(dwTmp, noUpdateRegistry); + } + } + // // Load save-state pathname *before* inserting any harddisk/disk images (for both init & reinit cases) diff --git a/source/Windows/AppleWin.cpp b/source/Windows/AppleWin.cpp index b5673ea6..142dc1a5 100644 --- a/source/Windows/AppleWin.cpp +++ b/source/Windows/AppleWin.cpp @@ -708,15 +708,6 @@ static void RepeatInitialization(void) g_cmdLine.clockMultiplier = 0.0; // Apply the memory expansion switches after loading the Apple II machine type -#ifdef RAMWORKS - if (g_cmdLine.uRamWorksExPages) - { - SetRamWorksMemorySize(g_cmdLine.uRamWorksExPages); - if (!g_cmdLine.auxSlotEmpty) - SetExpansionMemType(CT_RamWorksIII); - g_cmdLine.uRamWorksExPages = 0; // Don't reapply after a restart - } -#endif if (g_cmdLine.uSaturnBanks) { Saturn128K::SetSaturnMemorySize(g_cmdLine.uSaturnBanks); // Set number of banks before constructing Saturn card @@ -829,6 +820,18 @@ static void RepeatInitialization(void) // Aux slot +#ifdef RAMWORKS + if (g_cmdLine.uRamWorksExPages) + { + if (!g_cmdLine.auxSlotEmpty) + { + SetRamWorksMemorySize(g_cmdLine.uRamWorksExPages); + _ASSERT(g_cmdLine.auxSlotInsert == CT_RamWorksIII); // Implicitly set when using cmd line "-r banks" + } + g_cmdLine.uRamWorksExPages = 0; // Don't reapply after a restart + } +#endif + if (g_cmdLine.auxSlotEmpty) { GetCardMgr().RemoveAux(); @@ -836,7 +839,7 @@ static void RepeatInitialization(void) } else if (g_cmdLine.auxSlotInsert != CT_Empty) { - if (GetCardMgr().QueryAux() != g_cmdLine.auxSlotInsert) // Ignore if already got this card type in aux slot + if (GetCardMgr().QueryAux() != g_cmdLine.auxSlotInsert) // Ignore if already got this card type in aux slot, ie. via LoadConfiguration() { GetCardMgr().InsertAux(g_cmdLine.auxSlotInsert); SetExpansionMemType(g_cmdLine.auxSlotInsert);