diff --git a/AppleWinExpress2008.vcproj b/AppleWinExpress2008.vcproj index dd9a263e..a4a2b1ff 100644 --- a/AppleWinExpress2008.vcproj +++ b/AppleWinExpress2008.vcproj @@ -609,6 +609,18 @@ RelativePath=".\source\AY8910.h" > + + + + + + @@ -837,6 +849,14 @@ RelativePath=".\source\Disk.h" > + + + + diff --git a/AppleWinExpress2013.vcxproj b/AppleWinExpress2013.vcxproj index c827c5ef..96887062 100644 --- a/AppleWinExpress2013.vcxproj +++ b/AppleWinExpress2013.vcxproj @@ -24,6 +24,8 @@ + + @@ -62,6 +64,7 @@ + @@ -125,6 +128,7 @@ + @@ -135,6 +139,7 @@ + @@ -302,7 +307,7 @@ {0A960136-A00A-4D4B-805F-664D9950D2CA} Win32Proj - AppleWinExpress2013 + AppleWin AppleWin @@ -373,7 +378,7 @@ Windows true - htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies) + htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;ddraw.lib;%(AdditionalDependencies) "type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'" 5.01 @@ -428,7 +433,7 @@ true true true - htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies) + htmlhelp.lib;comctl32.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;advapi32.lib;shell32.lib;comdlg32.lib;ole32.lib;wsock32.lib;ddraw.lib;%(AdditionalDependencies) UseLinkTimeCodeGeneration "type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'" 5.01 diff --git a/AppleWinExpress2013.vcxproj.filters b/AppleWinExpress2013.vcxproj.filters index 3c5836c3..874f01f1 100644 --- a/AppleWinExpress2013.vcxproj.filters +++ b/AppleWinExpress2013.vcxproj.filters @@ -193,6 +193,12 @@ Source Files\Video + + Source Files\Emulator + + + Source Files\Disk + @@ -471,6 +477,15 @@ Source Files\Video + + Source Files\Emulator + + + Source Files\Emulator + + + Source Files\Disk + diff --git a/AppleWinExpress2015.vcxproj b/AppleWinExpress2015.vcxproj index ae6afd3f..d999211f 100644 --- a/AppleWinExpress2015.vcxproj +++ b/AppleWinExpress2015.vcxproj @@ -24,6 +24,8 @@ + + @@ -62,6 +64,7 @@ + @@ -125,6 +128,7 @@ + @@ -135,6 +139,7 @@ + @@ -302,7 +307,7 @@ {0A960136-A00A-4D4B-805F-664D9950D2CA} Win32Proj - AppleWinExpress2013 + AppleWin AppleWin diff --git a/AppleWinExpress2015.vcxproj.filters b/AppleWinExpress2015.vcxproj.filters index 3c5836c3..c275c50c 100644 --- a/AppleWinExpress2015.vcxproj.filters +++ b/AppleWinExpress2015.vcxproj.filters @@ -193,6 +193,12 @@ Source Files\Video + + Source Files\Disk + + + Source Files\Emulator + @@ -471,6 +477,15 @@ Source Files\Video + + Source Files\Disk + + + Source Files\Emulator + + + Source Files\Emulator + diff --git a/AppleWinExpress2017.vcxproj b/AppleWinExpress2017.vcxproj index 84487d38..70db63e9 100644 --- a/AppleWinExpress2017.vcxproj +++ b/AppleWinExpress2017.vcxproj @@ -24,6 +24,8 @@ + + @@ -62,6 +64,7 @@ + @@ -125,6 +128,7 @@ + @@ -135,6 +139,7 @@ + diff --git a/AppleWinExpress2017.vcxproj.filters b/AppleWinExpress2017.vcxproj.filters index 9903baf4..29a9dbfe 100644 --- a/AppleWinExpress2017.vcxproj.filters +++ b/AppleWinExpress2017.vcxproj.filters @@ -193,6 +193,12 @@ Source Files\Video + + Source Files\Disk + + + Source Files\Emulator + @@ -471,6 +477,15 @@ Source Files\Video + + Source Files\Disk + + + Source Files\Emulator + + + Source Files\Emulator + diff --git a/AppleWinExpress2019.vcxproj b/AppleWinExpress2019.vcxproj index b6ebc8c7..528d99fd 100644 --- a/AppleWinExpress2019.vcxproj +++ b/AppleWinExpress2019.vcxproj @@ -24,6 +24,8 @@ + + @@ -62,6 +64,7 @@ + @@ -125,6 +128,7 @@ + @@ -135,6 +139,7 @@ + diff --git a/AppleWinExpress2019.vcxproj.filters b/AppleWinExpress2019.vcxproj.filters index 9903baf4..1b9cfec1 100644 --- a/AppleWinExpress2019.vcxproj.filters +++ b/AppleWinExpress2019.vcxproj.filters @@ -193,6 +193,12 @@ Source Files\Video + + Source Files\Emulator + + + Source Files\Disk + @@ -471,6 +477,15 @@ Source Files\Video + + Source Files\Emulator + + + Source Files\Disk + + + Source Files\Emulator + diff --git a/source/Applewin.cpp b/source/Applewin.cpp index cb50d1fb..ebf779d8 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "Applewin.h" +#include "CardManager.h" #include "CPU.h" #include "Debug.h" #include "Disk.h" @@ -104,21 +105,8 @@ bool g_bDisableDirectSound = false; bool g_bDisableDirectSoundMockingboard = false; int g_nMemoryClearType = MIP_FF_FF_00_00; // Note: -1 = random MIP in Memory.cpp MemReset() +CardManager g_CardMgr; IPropertySheet& sg_PropertySheet = * new CPropertySheet; -CSuperSerialCard sg_SSC; -CMouseInterface sg_Mouse; -Disk2InterfaceCard sg_Disk2Card; - -SS_CARDTYPE g_Slot[8] = { - /*0*/ CT_LanguageCard, // Just for Apple II or II+ or similar clones - /*1*/ CT_GenericPrinter, - /*2*/ CT_SSC, - /*3*/ CT_Uthernet, - /*4*/ CT_Empty, - /*5*/ CT_Empty, - /*6*/ CT_Disk2, - /*7*/ CT_Empty }; -SS_CARDTYPE g_SlotAux = CT_Extended80Col; // For Apple //e and above HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed @@ -280,7 +268,7 @@ static void ContinueExecution(void) const bool bWasFullSpeed = g_bFullSpeed; g_bFullSpeed = (g_dwSpeed == SPEED_MAX) || bScrollLock_FullSpeed || - (sg_Disk2Card.IsConditionForFullSpeed() && !Spkr_IsActive() && !MB_IsActive()) || + (g_CardMgr.GetDisk2CardMgr().IsConditionForFullSpeed() && !Spkr_IsActive() && !MB_IsActive()) || IsDebugSteppingAtFullSpeed(); if (g_bFullSpeed) @@ -327,7 +315,7 @@ static void ContinueExecution(void) const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate); g_dwCyclesThisFrame += uActualCyclesExecuted; - sg_Disk2Card.UpdateDriveState(uActualCyclesExecuted); + g_CardMgr.GetDisk2CardMgr().UpdateDriveState(uActualCyclesExecuted); JoyUpdateButtonLatch(nExecutionPeriodUsec); // Button latch time is independent of CPU clock frequency PrintUpdate(uActualCyclesExecuted); MB_PeriodicUpdate(uActualCyclesExecuted); @@ -652,7 +640,8 @@ void LoadConfiguration(void) serialPortName, CSuperSerialCard::SIZEOF_SERIALCHOICE_ITEM)) { - sg_SSC.SetSerialPortName(serialPortName); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->SetSerialPortName(serialPortName); } REGLOAD_DEFAULT(TEXT(REGVALUE_EMULATION_SPEED), &g_dwSpeed, SPEED_NORMAL); @@ -661,7 +650,7 @@ void LoadConfiguration(void) DWORD dwEnhanceDisk; REGLOAD_DEFAULT(TEXT(REGVALUE_ENHANCE_DISK_SPEED), &dwEnhanceDisk, 1); - sg_Disk2Card.SetEnhanceDisk(dwEnhanceDisk ? true : false); + g_CardMgr.GetDisk2CardMgr().SetEnhanceDisk(dwEnhanceDisk ? true : false); // @@ -720,9 +709,9 @@ void LoadConfiguration(void) sg_PropertySheet.SetMouseRestrictToWindow(dwTmp); if(REGLOAD(TEXT(REGVALUE_SLOT4), &dwTmp)) - g_Slot[4] = (SS_CARDTYPE) dwTmp; + g_CardMgr.Insert(4, (SS_CARDTYPE)dwTmp); if(REGLOAD(TEXT(REGVALUE_SLOT5), &dwTmp)) - g_Slot[5] = (SS_CARDTYPE) dwTmp; + g_CardMgr.Insert(5, (SS_CARDTYPE)dwTmp); // @@ -744,8 +733,7 @@ void LoadConfiguration(void) GetCurrentDirectory(sizeof(szFilename), szFilename); SetCurrentImageDir(szFilename); - sg_Disk2Card.LoadLastDiskImage(DRIVE_1); - sg_Disk2Card.LoadLastDiskImage(DRIVE_2); + g_CardMgr.GetDisk2CardMgr().LoadLastDiskImage(); // @@ -1107,12 +1095,14 @@ static std::string GetFullPath(LPCSTR szFileName) return strPathName; } -static bool DoDiskInsert(const int nDrive, LPCSTR szFileName) +static bool DoDiskInsert(const UINT slot, const int nDrive, LPCSTR szFileName) { + Disk2InterfaceCard* pDisk2Card = dynamic_cast (g_CardMgr.GetObj(slot)); + std::string strPathName = GetFullPath(szFileName); if (strPathName.empty()) return false; - ImageError_e Error = sg_Disk2Card.InsertDisk(nDrive, strPathName.c_str(), IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE); + ImageError_e Error = pDisk2Card->InsertDisk(nDrive, strPathName.c_str(), IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE); return Error == eIMAGE_ERROR_NONE; } @@ -1125,8 +1115,10 @@ static bool DoHardDiskInsert(const int nDrive, LPCSTR szFileName) return bRes ? true : false; } -static void InsertFloppyDisks(LPSTR szImageName_drive[NUM_DRIVES], bool& bBoot) +static void InsertFloppyDisks(const UINT slot, LPSTR szImageName_drive[NUM_DRIVES], bool& bBoot) { + _ASSERT(slot == 5 || slot == 6); + if (!szImageName_drive[DRIVE_1] && !szImageName_drive[DRIVE_2]) return; @@ -1134,16 +1126,16 @@ static void InsertFloppyDisks(LPSTR szImageName_drive[NUM_DRIVES], bool& bBoot) if (szImageName_drive[DRIVE_1]) { - bRes = DoDiskInsert(DRIVE_1, szImageName_drive[DRIVE_1]); - LogFileOutput("Init: DoDiskInsert(D1), res=%d\n", bRes); + bRes = DoDiskInsert(slot, DRIVE_1, szImageName_drive[DRIVE_1]); + LogFileOutput("Init: S%d, DoDiskInsert(D1), res=%d\n", slot, bRes); FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); // floppy activity LEDs and floppy buttons bBoot = true; } if (szImageName_drive[DRIVE_2]) { - bRes |= DoDiskInsert(DRIVE_2, szImageName_drive[DRIVE_2]); - LogFileOutput("Init: DoDiskInsert(D2), res=%d\n", bRes); + bRes |= DoDiskInsert(slot, DRIVE_2, szImageName_drive[DRIVE_2]); + LogFileOutput("Init: S%d, DoDiskInsert(D2), res=%d\n", slot, bRes); } if (!bRes) @@ -1233,10 +1225,13 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) bool bBoot = false; bool bChangedDisplayResolution = false; bool bSlot0LanguageCard = false; - bool bSlotEmpty[NUM_SLOTS] = {false,false,false,false,false,false,false,false}; + bool bSlotEmpty[NUM_SLOTS] = {}; bool bSlot7EmptyOnExit = false; + SS_CARDTYPE slotInsert[NUM_SLOTS]; UINT bestWidth = 0, bestHeight = 0; - LPSTR szImageName_drive[NUM_DRIVES] = {NULL,NULL}; + const UINT SLOT5 = 5; + const UINT SLOT6 = 6; + LPSTR szImageName_drive[NUM_SLOTS][NUM_DRIVES] = {}; LPSTR szImageName_harddisk[NUM_HARDDISKS] = {NULL,NULL}; LPSTR szSnapshotName = NULL; const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput @@ -1250,6 +1245,14 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) double clockMultiplier = 0.0; // 0 => not set from cmd-line eApple2Type model = A2TYPE_MAX; + for (UINT i = 0; i < NUM_SLOTS; i++) + { + bSlotEmpty[i] = false; + slotInsert[i] = CT_Empty; + szImageName_drive[i][DRIVE_1] = NULL; + szImageName_drive[i][DRIVE_2] = NULL; + } + while (*lpCmdLine) { LPSTR lpNextArg = GetNextArg(lpCmdLine); @@ -1266,13 +1269,13 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); - szImageName_drive[DRIVE_1] = lpCmdLine; + szImageName_drive[SLOT6][DRIVE_1] = lpCmdLine; } else if (strcmp(lpCmdLine, "-d2") == 0) { lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); - szImageName_drive[DRIVE_2] = lpCmdLine; + szImageName_drive[SLOT6][DRIVE_2] = lpCmdLine; } else if (strcmp(lpCmdLine, "-h1") == 0) { @@ -1286,13 +1289,38 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) lpNextArg = GetNextArg(lpNextArg); szImageName_harddisk[HARDDISK_2] = lpCmdLine; } - else if (lpCmdLine[0] == '-' && lpCmdLine[1] == 's' && lpCmdLine[2] >= '1' && lpCmdLine[2] <= '7' && lpCmdLine[3] == 0) + else if (lpCmdLine[0] == '-' && lpCmdLine[1] == 's' && lpCmdLine[2] >= '1' && lpCmdLine[2] <= '7') { const UINT slot = lpCmdLine[2] - '0'; - lpCmdLine = GetCurrArg(lpNextArg); - lpNextArg = GetNextArg(lpNextArg); - if (strcmp(lpCmdLine, "empty") == 0) - bSlotEmpty[slot] = true; + + if (lpCmdLine[3] == 0) // -s[1..7] + { + lpCmdLine = GetCurrArg(lpNextArg); + lpNextArg = GetNextArg(lpNextArg); + if (strcmp(lpCmdLine, "empty") == 0) + bSlotEmpty[slot] = true; + if (strcmp(lpCmdLine, "diskii") == 0) + slotInsert[slot] = CT_Disk2; + } + else if (lpCmdLine[3] == 'd' && (lpCmdLine[4] == '1' || lpCmdLine[4] == '2')) // -s[1..7]d[1|2] + { + const UINT drive = lpCmdLine[4] == '1' ? DRIVE_1 : DRIVE_2; + + if (slot != 5 && slot != 6) + { + LogFileOutput("Unsupported arg: %s\n", lpCmdLine); + } + else + { + lpCmdLine = GetCurrArg(lpNextArg); + lpNextArg = GetNextArg(lpNextArg); + szImageName_drive[slot][drive] = lpCmdLine; + } + } + else + { + LogFileOutput("Unsupported arg: %s\n", lpCmdLine); + } } else if (strcmp(lpCmdLine, "-s7-empty-on-exit") == 0) { @@ -1468,7 +1496,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) } else if ((strcmp(lpCmdLine, "-dcd") == 0) || (strcmp(lpCmdLine, "-modem") == 0)) // GH#386 { - sg_SSC.SupportDCD(true); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->SupportDCD(true); } else if (strcmp(lpCmdLine, "-alt-enter=toggle-full-screen") == 0) // GH#556 { @@ -1697,20 +1726,35 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) LogFileOutput("Main: FrameCreateWindow() - post\n"); // Allow the 4 hardcoded slots to be configurated as empty - if (bSlotEmpty[1]) - g_Slot[1] = CT_Empty; - if (bSlotEmpty[2]) - g_Slot[2] = CT_Empty; - if (bSlotEmpty[3]) - g_Slot[3] = CT_Empty; - if (bSlotEmpty[6]) - g_Slot[6] = CT_Empty; + if (bSlotEmpty[SLOT1]) + g_CardMgr.Remove(SLOT1); + if (bSlotEmpty[SLOT2]) + g_CardMgr.Remove(SLOT2); + if (bSlotEmpty[SLOT3]) + g_CardMgr.Remove(SLOT3); + if (bSlotEmpty[SLOT6]) + g_CardMgr.Remove(SLOT6); + + if (slotInsert[5] != CT_Empty) + { + if (g_CardMgr.QuerySlot(SLOT4) == CT_MockingboardC && slotInsert[SLOT5] != CT_MockingboardC) // Currently MB occupies slot4+5 when enabled + { + g_CardMgr.Remove(SLOT4); + g_CardMgr.Remove(SLOT5); + } + + g_CardMgr.Insert(SLOT5, slotInsert[SLOT5]); + } // Pre: may need g_hFrameWindow for MessageBox errors // Post: may enable HDD, required for MemInitialize()->MemInitializeIO() { - InsertFloppyDisks(szImageName_drive, bBoot); - szImageName_drive[DRIVE_1] = szImageName_drive[DRIVE_2] = NULL; // Don't insert on a restart + bool temp = false; + InsertFloppyDisks(SLOT5, szImageName_drive[SLOT5], temp); + //szImageName_drive[SLOT5][DRIVE_1] = szImageName_drive[SLOT5][DRIVE_2] = NULL; // *Do* insert on a restart (since no way they could have changed) + + InsertFloppyDisks(SLOT6, szImageName_drive[SLOT6], bBoot); + szImageName_drive[SLOT6][DRIVE_1] = szImageName_drive[SLOT6][DRIVE_2] = NULL; // Don't insert on a restart InsertHardDisks(szImageName_harddisk, bBoot); szImageName_harddisk[HARDDISK_1] = szImageName_harddisk[HARDDISK_2] = NULL; // Don't insert on a restart @@ -1743,8 +1787,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) LogFileOutput("Main: HookFilterForKeyboard()\n"); } - // Need to test if it's safe to call ResetMachineState(). In the meantime, just call DiskReset(): - sg_Disk2Card.Reset(true); // Switch from a booting A][+ to a non-autostart A][, so need to turn off floppy motor + // Need to test if it's safe to call ResetMachineState(). In the meantime, just call Disk2Card's Reset(): + g_CardMgr.GetDisk2CardMgr().Reset(true); // Switch from a booting A][+ to a non-autostart A][, so need to turn off floppy motor LogFileOutput("Main: DiskReset()\n"); HD_Reset(); // GH#515 LogFileOutput("Main: HDDReset()\n"); @@ -1836,6 +1880,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) } } + SetMouseCardInstalled( g_CardMgr.IsMouseCardInstalled() ); + // ENTER THE MAIN MESSAGE LOOP LogFileOutput("Main: EnterMessageLoop()\n"); EnterMessageLoop(); @@ -1850,9 +1896,13 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) MB_Reset(); LogFileOutput("Main: MB_Reset()\n"); - sg_Mouse.Uninitialize(); // Maybe restarting due to switching slot-4 card from MouseCard to Mockingboard - sg_Mouse.Reset(); // Deassert any pending IRQs - GH#514 - LogFileOutput("Main: sg_Mouse.Uninitialize()\n"); + CMouseInterface* pMouseCard = g_CardMgr.GetMouseCard(); + if (pMouseCard) + { +// pMouseCard->Uninitialize(); // Maybe restarting due to switching slot-4 card from MouseCard to Mockingboard + pMouseCard->Reset(); // Deassert any pending IRQs - GH#514 + LogFileOutput("Main: CMouseInterface::Uninitialize()\n"); + } DSUninit(); LogFileOutput("Main: DSUninit()\n"); diff --git a/source/Applewin.h b/source/Applewin.h index 446ba2b3..a340f416 100644 --- a/source/Applewin.h +++ b/source/Applewin.h @@ -1,5 +1,6 @@ #pragma once +#include "Card.h" #include "SaveState_Structs_common.h" #include "Common.h" @@ -51,8 +52,7 @@ extern bool g_bDisableDirectSound; // Cmd line switch: don't init DS (s extern bool g_bDisableDirectSoundMockingboard; // Cmd line switch: don't init MB support extern int g_nMemoryClearType; // Cmd line switch: use specific MIP (Memory Initialization Pattern) -extern SS_CARDTYPE g_Slot[NUM_SLOTS]; -extern SS_CARDTYPE g_SlotAux; +extern class CardManager g_CardMgr; extern HANDLE g_hCustomRomF8; // NULL if no custom rom diff --git a/source/CPU.cpp b/source/CPU.cpp index b9e02e4e..3fd31232 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -87,6 +87,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "Applewin.h" +#include "CardManager.h" #include "CPU.h" #include "Frame.h" #include "Memory.h" @@ -145,6 +146,8 @@ static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line static bool g_irqDefer1Opcode = false; +static bool g_isMouseCardInstalled = false; + // static eCpuType g_MainCPU = CPU_65C02; @@ -200,6 +203,11 @@ void ResetCyclesExecutedForDebugger(void) g_nCyclesExecuted = 0; } +void SetMouseCardInstalled(bool installed) +{ + g_isMouseCardInstalled = installed; +} + // #include "CPU/cpu_general.inl" @@ -455,8 +463,8 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles, const boo if (MB_UpdateCycles(uExecutedCycles)) g_irqOnLastOpcodeCycle = true; - if (sg_Mouse.IsActive()) - sg_Mouse.SetVBlank( !VideoGetVblBar(uExecutedCycles) ); + if (g_isMouseCardInstalled) + g_CardMgr.GetMouseCard()->SetVBlank( !VideoGetVblBar(uExecutedCycles) ); } // GH#608: IRQ needs to occur within 17 cycles (6 opcodes) of configuring the timer interrupt diff --git a/source/CPU.h b/source/CPU.h index 20d481e4..28d0e920 100644 --- a/source/CPU.h +++ b/source/CPU.h @@ -45,3 +45,4 @@ void SetActiveCpu(eCpuType cpu); bool Is6502InterruptEnabled(void); void ResetCyclesExecutedForDebugger(void); +void SetMouseCardInstalled(bool installed); diff --git a/source/Card.h b/source/Card.h new file mode 100644 index 00000000..6d2ccb3f --- /dev/null +++ b/source/Card.h @@ -0,0 +1,65 @@ +#pragma once + +enum SS_CARDTYPE +{ + CT_Empty = 0, + CT_Disk2, // Apple Disk][ + CT_SSC, // Apple Super Serial Card + CT_MockingboardC, // Soundcard + CT_GenericPrinter, + CT_GenericHDD, // Hard disk + CT_GenericClock, + CT_MouseInterface, + CT_Z80, + CT_Phasor, // Soundcard + CT_Echo, // Soundcard + CT_SAM, // Soundcard: Software Automated Mouth + CT_80Col, // 80 column card (1K) + CT_Extended80Col, // Extended 80-col card (64K) + CT_RamWorksIII, // RamWorksIII (up to 8MB) + CT_Uthernet, + CT_LanguageCard, // Apple][ or ][+ in slot-0 + CT_LanguageCardIIe, // Apple//e LC instance (not a card) + CT_Saturn128K, // Saturn 128K (but may be populated with less RAM, in multiples of 16K) +}; + +enum SLOTS { SLOT0=0, SLOT1, SLOT2, SLOT3, SLOT4, SLOT5, SLOT6, SLOT7 }; + +class Card +{ +public: + Card(void) : m_type(CT_Empty) {} + Card(SS_CARDTYPE type) : m_type(type) {} + virtual ~Card(void) {} + + virtual void Init(void) = 0; + virtual void Reset(const bool powerCycle) = 0; + SS_CARDTYPE QueryType(void) { return m_type; } + +private: + SS_CARDTYPE m_type; +}; + +// + +class EmptyCard : public Card +{ +public: + EmptyCard(void) {} + virtual ~EmptyCard(void) {} + + virtual void Init(void) {}; + virtual void Reset(const bool powerCycle) {}; +}; + +// + +class DummyCard : public Card // For cards that currently can't be instantiated (ie. don't exist as a class) +{ +public: + DummyCard(SS_CARDTYPE type) : Card(type) {} + virtual ~DummyCard(void) {} + + virtual void Init(void) {}; + virtual void Reset(const bool powerCycle) {}; +}; diff --git a/source/CardManager.cpp b/source/CardManager.cpp new file mode 100644 index 00000000..f5b17f27 --- /dev/null +++ b/source/CardManager.cpp @@ -0,0 +1,155 @@ +/* +AppleWin : An Apple //e emulator for Windows + +Copyright (C) 1994-1996, Michael O'Brien +Copyright (C) 1999-2001, Oliver Schmidt +Copyright (C) 2002-2005, Tom Charlesworth +Copyright (C) 2006-2019, Tom Charlesworth, Michael Pohoreski, Nick Westgate + +AppleWin is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +AppleWin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with AppleWin; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* Description: Card Manager + * + * Author: Various + * + */ + +#include "StdAfx.h" + +#include "AppleWin.h" +#include "CardManager.h" + +#include "Disk.h" +#include "MouseInterface.h" +#include "SerialComms.h" + +void CardManager::Insert(UINT slot, SS_CARDTYPE type) +{ + if (type == CT_Empty) + return Remove(slot); + + RemoveInternal(slot); + + switch (type) + { + case CT_Disk2: + m_slot[slot] = new Disk2InterfaceCard; + break; + case CT_SSC: + _ASSERT(m_pSSC == NULL); + if (m_pSSC) break; // Only support one SSC + m_slot[slot] = m_pSSC = new CSuperSerialCard; + break; + case CT_MockingboardC: + m_slot[slot] = new DummyCard(type); + break; + case CT_GenericPrinter: + m_slot[slot] = new DummyCard(type); + break; + case CT_GenericHDD: + m_slot[slot] = new DummyCard(type); + break; + case CT_GenericClock: + m_slot[slot] = new DummyCard(type); + break; + case CT_MouseInterface: + _ASSERT(m_pMouseCard == NULL); + if (m_pMouseCard) break; // Only support one Mouse card + m_slot[slot] = m_pMouseCard = new CMouseInterface(slot); + break; + case CT_Z80: + m_slot[slot] = new DummyCard(type); + break; + case CT_Phasor: + m_slot[slot] = new DummyCard(type); + break; + case CT_Echo: + m_slot[slot] = new DummyCard(type); + break; + case CT_SAM: + m_slot[slot] = new DummyCard(type); + break; + case CT_Uthernet: + m_slot[slot] = new DummyCard(type); + break; + + case CT_LanguageCard: + case CT_Saturn128K: + { + if (slot != 0) + { + _ASSERT(0); + break; + } + } + m_slot[slot] = new DummyCard(type); + break; + + case CT_LanguageCardIIe: // not a card + default: + _ASSERT(0); + break; + } + + if (m_slot[slot] == NULL) + m_slot[slot] = new EmptyCard; +} + +void CardManager::RemoveInternal(UINT slot) +{ + if (m_slot[slot] && m_slot[slot]->QueryType() == CT_MouseInterface) + m_pMouseCard = NULL; + + if (m_slot[slot] && m_slot[slot]->QueryType() == CT_SSC) + m_pSSC = NULL; + + delete m_slot[slot]; + m_slot[slot] = NULL; +} + +void CardManager::Remove(UINT slot) +{ + RemoveInternal(slot); + m_slot[slot] = new EmptyCard; +} + +void CardManager::InsertAux(SS_CARDTYPE type) +{ + if (type == CT_Empty) + return RemoveAux(); + + switch (type) + { + case CT_80Col: + m_aux = new DummyCard(type); + break; + case CT_Extended80Col: + m_aux = new DummyCard(type); + break; + case CT_RamWorksIII: + m_aux = new DummyCard(type); + break; + default: + _ASSERT(0); + break; + } +} + +void CardManager::RemoveAux(void) +{ + delete m_aux; + m_aux = new EmptyCard; +} diff --git a/source/CardManager.h b/source/CardManager.h new file mode 100644 index 00000000..ae317c69 --- /dev/null +++ b/source/CardManager.h @@ -0,0 +1,56 @@ +#pragma once + +#include "Card.h" +#include "Disk2CardManager.h" + +class CardManager +{ +public: + CardManager(void) : + m_pMouseCard(NULL), + m_pSSC(NULL) + { + Insert(0, CT_Empty); + Insert(1, CT_GenericPrinter); + Insert(2, CT_SSC); + Insert(3, CT_Uthernet); + Insert(4, CT_Empty); + Insert(5, CT_Empty); + Insert(6, CT_Disk2); + Insert(7, CT_Empty); + InsertAux(CT_Extended80Col); // For Apple //e and above + } + ~CardManager(void) + { + for (UINT i=0; iQueryType(); } + Card* GetObj(UINT slot) { SS_CARDTYPE t=QuerySlot(slot); _ASSERT(t==CT_SSC || t==CT_MouseInterface || t==CT_Disk2); return m_slot[slot]; } + + void InsertAux(SS_CARDTYPE type); + 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 + + // + + Disk2CardManager& GetDisk2CardMgr(void) { return m_disk2CardMgr; } + class CMouseInterface* GetMouseCard(void) { return m_pMouseCard; } + bool IsMouseCardInstalled(void) { return m_pMouseCard != NULL; } + class CSuperSerialCard* GetSSC(void) { return m_pSSC; } + bool IsSSCInstalled(void) { return m_pSSC != NULL; } + +private: + void RemoveInternal(UINT slot); + + Card* m_slot[NUM_SLOTS]; + Card* m_aux; + Disk2CardManager m_disk2CardMgr; + class CMouseInterface* m_pMouseCard; + class CSuperSerialCard* m_pSSC; +}; diff --git a/source/Configuration/Config.h b/source/Configuration/Config.h index aae080dc..2acb64b4 100644 --- a/source/Configuration/Config.h +++ b/source/Configuration/Config.h @@ -1,6 +1,7 @@ #pragma once #include "../Applewin.h" +#include "../CardManager.h" #include "../CPU.h" #include "../DiskImage.h" // Disk_Status_e #include "../Harddisk.h" // HD_CardIsEnabled() @@ -19,9 +20,9 @@ public: m_bEnableTheFreezesF8Rom = bEnableTheFreezesF8Rom; memset(&m_Slot, 0, sizeof(m_Slot)); m_SlotAux = CT_Empty; - m_Slot[4] = g_Slot[4]; - m_Slot[5] = g_Slot[5]; - m_Slot[7] = g_Slot[7]; + m_Slot[SLOT4] = g_CardMgr.QuerySlot(SLOT4); + m_Slot[SLOT5] = g_CardMgr.QuerySlot(SLOT5); + m_Slot[SLOT7] = g_CardMgr.QuerySlot(SLOT7); } const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other) diff --git a/source/Configuration/PageConfig.cpp b/source/Configuration/PageConfig.cpp index 6fdf6bb1..ffe3846e 100644 --- a/source/Configuration/PageConfig.cpp +++ b/source/Configuration/PageConfig.cpp @@ -203,8 +203,16 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM CheckDlgButton(hWnd, IDC_CHECK_VERTICAL_BLEND, IsVideoStyle(VS_COLOR_VERTICAL_BLEND) ? BST_CHECKED : BST_UNCHECKED); EnableWindow(GetDlgItem(hWnd, IDC_CHECK_VERTICAL_BLEND), (GetVideoType() == VT_COLOR_MONITOR_RGB) ? TRUE : FALSE); - m_PropertySheetHelper.FillComboBox(hWnd,IDC_SERIALPORT, sg_SSC.GetSerialPortChoices(), sg_SSC.GetSerialPort()); - EnableWindow(GetDlgItem(hWnd, IDC_SERIALPORT), !sg_SSC.IsActive() ? TRUE : FALSE); + if (g_CardMgr.IsSSCInstalled()) + { + CSuperSerialCard* pSSC = g_CardMgr.GetSSC(); + m_PropertySheetHelper.FillComboBox(hWnd, IDC_SERIALPORT, pSSC->GetSerialPortChoices(), pSSC->GetSerialPort()); + EnableWindow(GetDlgItem(hWnd, IDC_SERIALPORT), !pSSC->IsActive() ? TRUE : FALSE); + } + else + { + EnableWindow(GetDlgItem(hWnd, IDC_SERIALPORT), FALSE); + } CheckDlgButton(hWnd, IDC_CHECK_50HZ_VIDEO, (GetVideoRefreshRate() == VR_50HZ) ? BST_CHECKED : BST_UNCHECKED); @@ -333,12 +341,16 @@ void CPageConfig::DlgOK(HWND hWnd) // - const DWORD uNewSerialPort = (DWORD) SendDlgItemMessage(hWnd, IDC_SERIALPORT, CB_GETCURSEL, 0, 0); - sg_SSC.CommSetSerialPort(hWnd, uNewSerialPort); - RegSaveString( TEXT(REG_CONFIG), - TEXT(REGVALUE_SERIAL_PORT_NAME), - TRUE, - sg_SSC.GetSerialPortName() ); + if (g_CardMgr.IsSSCInstalled()) + { + CSuperSerialCard* pSSC = g_CardMgr.GetSSC(); + const DWORD uNewSerialPort = (DWORD) SendDlgItemMessage(hWnd, IDC_SERIALPORT, CB_GETCURSEL, 0, 0); + pSSC->CommSetSerialPort(hWnd, uNewSerialPort); + RegSaveString( TEXT(REG_CONFIG), + TEXT(REGVALUE_SERIAL_PORT_NAME), + TRUE, + pSSC->GetSerialPortName() ); + } // diff --git a/source/Configuration/PageDisk.cpp b/source/Configuration/PageDisk.cpp index b0f7b286..eae4b43c 100644 --- a/source/Configuration/PageDisk.cpp +++ b/source/Configuration/PageDisk.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "../Applewin.h" +#include "../CardManager.h" #include "../Disk.h" // Drive_e, Disk_Status_e #include "../Frame.h" #include "../Registry.h" @@ -89,14 +90,14 @@ BOOL CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM l case IDC_COMBO_DISK1: if (HIWORD(wparam) == CBN_SELCHANGE) { - HandleDiskCombo(hWnd, DRIVE_1, LOWORD(wparam)); + HandleFloppyDriveCombo(hWnd, DRIVE_1, LOWORD(wparam)); FrameRefreshStatus(DRAW_BUTTON_DRIVES); } break; case IDC_COMBO_DISK2: if (HIWORD(wparam) == CBN_SELCHANGE) { - HandleDiskCombo(hWnd, DRIVE_2, LOWORD(wparam)); + HandleFloppyDriveCombo(hWnd, DRIVE_2, LOWORD(wparam)); FrameRefreshStatus(DRAW_BUTTON_DRIVES); } break; @@ -130,23 +131,12 @@ BOOL CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM l case WM_INITDIALOG: { - m_PropertySheetHelper.FillComboBox(hWnd, IDC_DISKTYPE, m_discchoices, sg_Disk2Card.GetEnhanceDisk() ? 1 : 0); - m_PropertySheetHelper.FillComboBox(hWnd, IDC_COMBO_DISK1, m_defaultDiskOptions, -1); - m_PropertySheetHelper.FillComboBox(hWnd, IDC_COMBO_DISK2, m_defaultDiskOptions, -1); + m_PropertySheetHelper.FillComboBox(hWnd, IDC_DISKTYPE, m_discchoices, g_CardMgr.GetDisk2CardMgr().GetEnhanceDisk() ? 1 : 0); - if (!sg_Disk2Card.GetFullName(DRIVE_1).empty()) - { - SendDlgItemMessage(hWnd, IDC_COMBO_DISK1, CB_INSERTSTRING, 0, (LPARAM)sg_Disk2Card.GetFullName(DRIVE_1).c_str()); - SendDlgItemMessage(hWnd, IDC_COMBO_DISK1, CB_SETCURSEL, 0, 0); - } + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + InitComboFloppyDrive(hWnd, SLOT6); - if (!sg_Disk2Card.GetFullName(DRIVE_2).empty()) - { - SendDlgItemMessage(hWnd, IDC_COMBO_DISK2, CB_INSERTSTRING, 0, (LPARAM)sg_Disk2Card.GetFullName(DRIVE_2).c_str()); - SendDlgItemMessage(hWnd, IDC_COMBO_DISK2, CB_SETCURSEL, 0, 0); - } - - InitComboHDD(hWnd); + InitComboHDD(hWnd, SLOT7); TCHAR PathToCiderPress[MAX_PATH]; RegLoadString(TEXT(REG_CONFIG), REGVALUE_CIDERPRESSLOC, 1, PathToCiderPress, MAX_PATH, TEXT("")); @@ -166,7 +156,27 @@ BOOL CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM l return FALSE; } -void CPageDisk::InitComboHDD(HWND hWnd) +void CPageDisk::InitComboFloppyDrive(HWND hWnd, UINT slot) +{ + Disk2InterfaceCard* pDisk2Card = dynamic_cast(g_CardMgr.GetObj(slot)); + + m_PropertySheetHelper.FillComboBox(hWnd, IDC_COMBO_DISK1, m_defaultDiskOptions, -1); + m_PropertySheetHelper.FillComboBox(hWnd, IDC_COMBO_DISK2, m_defaultDiskOptions, -1); + + if (!pDisk2Card->GetFullName(DRIVE_1).empty()) + { + SendDlgItemMessage(hWnd, IDC_COMBO_DISK1, CB_INSERTSTRING, 0, (LPARAM)pDisk2Card->GetFullName(DRIVE_1).c_str()); + SendDlgItemMessage(hWnd, IDC_COMBO_DISK1, CB_SETCURSEL, 0, 0); + } + + if (!pDisk2Card->GetFullName(DRIVE_2).empty()) + { + SendDlgItemMessage(hWnd, IDC_COMBO_DISK2, CB_INSERTSTRING, 0, (LPARAM)pDisk2Card->GetFullName(DRIVE_2).c_str()); + SendDlgItemMessage(hWnd, IDC_COMBO_DISK2, CB_SETCURSEL, 0, 0); + } +} + +void CPageDisk::InitComboHDD(HWND hWnd, UINT /*slot*/) { m_PropertySheetHelper.FillComboBox(hWnd, IDC_COMBO_HDD1, m_defaultHDDOptions, -1); m_PropertySheetHelper.FillComboBox(hWnd, IDC_COMBO_HDD2, m_defaultHDDOptions, -1); @@ -187,9 +197,9 @@ void CPageDisk::InitComboHDD(HWND hWnd) void CPageDisk::DlgOK(HWND hWnd) { const bool bNewEnhanceDisk = SendDlgItemMessage(hWnd, IDC_DISKTYPE,CB_GETCURSEL, 0, 0) ? true : false; - if (bNewEnhanceDisk != sg_Disk2Card.GetEnhanceDisk()) + if (bNewEnhanceDisk != g_CardMgr.GetDisk2CardMgr().GetEnhanceDisk()) { - sg_Disk2Card.SetEnhanceDisk(bNewEnhanceDisk); + g_CardMgr.GetDisk2CardMgr().SetEnhanceDisk(bNewEnhanceDisk); REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), (DWORD)bNewEnhanceDisk); } @@ -288,8 +298,12 @@ void CPageDisk::HandleHDDCombo(HWND hWnd, UINT driveSelected, UINT comboSelected } } -void CPageDisk::HandleDiskCombo(HWND hWnd, UINT driveSelected, UINT comboSelected) +void CPageDisk::HandleFloppyDriveCombo(HWND hWnd, UINT driveSelected, UINT comboSelected) { + Disk2InterfaceCard* pDisk2Card = (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + ? dynamic_cast(g_CardMgr.GetObj(SLOT6)) + : NULL; + // Search from "select floppy drive" DWORD dwOpenDialogIndex = (DWORD)SendDlgItemMessage(hWnd, comboSelected, CB_FINDSTRINGEXACT, -1, (LPARAM)&m_defaultDiskOptions[0]); DWORD dwComboSelection = (DWORD)SendDlgItemMessage(hWnd, comboSelected, CB_GETCURSEL, 0, 0); @@ -299,7 +313,8 @@ void CPageDisk::HandleDiskCombo(HWND hWnd, UINT driveSelected, UINT comboSelecte if (dwComboSelection == dwOpenDialogIndex) { EnableDisk(hWnd, FALSE); // Prevent multiple Selection dialogs to be triggered - bool bRes = sg_Disk2Card.UserSelectNewDiskImage(driveSelected); + bool bRes = false; + if (pDisk2Card) bRes = pDisk2Card->UserSelectNewDiskImage(driveSelected); EnableDisk(hWnd, TRUE); if (!bRes) @@ -316,13 +331,15 @@ void CPageDisk::HandleDiskCombo(HWND hWnd, UINT driveSelected, UINT comboSelecte SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0); } - SendDlgItemMessage(hWnd, comboSelected, CB_INSERTSTRING, 0, (LPARAM)sg_Disk2Card.GetFullName(driveSelected).c_str()); + std::string fullname; + if (pDisk2Card) fullname = pDisk2Card->GetFullName(driveSelected); + SendDlgItemMessage(hWnd, comboSelected, CB_INSERTSTRING, 0, (LPARAM)fullname.c_str()); SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0); // If the FD was in the other combo, remove now DWORD comboOther = (comboSelected == IDC_COMBO_DISK1) ? IDC_COMBO_DISK2 : IDC_COMBO_DISK1; - DWORD duplicated = (DWORD)SendDlgItemMessage(hWnd, comboOther, CB_FINDSTRINGEXACT, -1, (LPARAM)sg_Disk2Card.GetFullName(driveSelected).c_str()); + DWORD duplicated = (DWORD)SendDlgItemMessage(hWnd, comboOther, CB_FINDSTRINGEXACT, -1, (LPARAM)fullname.c_str()); if (duplicated != CB_ERR) { SendDlgItemMessage(hWnd, comboOther, CB_DELETESTRING, duplicated, 0); @@ -337,7 +354,7 @@ void CPageDisk::HandleDiskCombo(HWND hWnd, UINT driveSelected, UINT comboSelecte if (RemovalConfirmation(uCommand)) { // Eject selected disk - sg_Disk2Card.EjectDisk(driveSelected); + if (pDisk2Card) pDisk2Card->EjectDisk(driveSelected); // Remove drive from list SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0); } @@ -357,7 +374,7 @@ void CPageDisk::HandleHDDSwap(HWND hWnd) if (!HD_ImageSwap()) return; - InitComboHDD(hWnd); + InitComboHDD(hWnd, SLOT7); } UINT CPageDisk::RemovalConfirmation(UINT uCommand) diff --git a/source/Configuration/PageDisk.h b/source/Configuration/PageDisk.h index 89c2e7d1..b137a4de 100644 --- a/source/Configuration/PageDisk.h +++ b/source/Configuration/PageDisk.h @@ -25,11 +25,12 @@ protected: private: void InitOptions(HWND hWnd); - void InitComboHDD(HWND hWnd); + void InitComboFloppyDrive(HWND hWnd, UINT slot); + void InitComboHDD(HWND hWnd, UINT slot); void EnableHDD(HWND hWnd, BOOL bEnable); void EnableDisk(HWND hWnd, BOOL bEnable); void HandleHDDCombo(HWND hWnd, UINT driveSelected, UINT comboSelected); - void HandleDiskCombo(HWND hWnd, UINT driveSelected, UINT comboSelected); + void HandleFloppyDriveCombo(HWND hWnd, UINT driveSelected, UINT comboSelected); void HandleHDDSwap(HWND hWnd); UINT RemovalConfirmation(UINT uCommand); diff --git a/source/Configuration/PageSound.cpp b/source/Configuration/PageSound.cpp index 59fe9a6e..e876f0d3 100644 --- a/source/Configuration/PageSound.cpp +++ b/source/Configuration/PageSound.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../SaveState_Structs_common.h" #include "../Common.h" +#include "../CardManager.h" #include "../Mockingboard.h" #include "../Registry.h" #include "../Speaker.h" @@ -116,7 +117,7 @@ BOOL CPageSound::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM SendDlgItemMessage(hWnd,IDC_MB_VOLUME,TBM_SETTICFREQ,10,0); SendDlgItemMessage(hWnd,IDC_MB_VOLUME,TBM_SETPOS,1,MB_GetVolume()); - if (g_Slot[5] == CT_SAM) + if (g_CardMgr.QuerySlot(SLOT5) == CT_SAM) m_NewCardType = CT_SAM; else m_NewCardType = MB_GetSoundcardType(); // Reinit 1st time page is activated (fires before PSN_SETACTIVE) diff --git a/source/Configuration/PropertySheetHelper.cpp b/source/Configuration/PropertySheetHelper.cpp index d5f05651..a00fdf2f 100644 --- a/source/Configuration/PropertySheetHelper.cpp +++ b/source/Configuration/PropertySheetHelper.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "../Applewin.h" // g_nAppMode, g_uScrollLockToggle, sg_PropertySheet +#include "../CardManager.h" #include "../Disk.h" #include "../Frame.h" #include "../Log.h" @@ -124,7 +125,11 @@ void CPropertySheetHelper::SetSlot(UINT slot, SS_CARDTYPE newCardType) if (slot >= NUM_SLOTS) return; - g_Slot[slot] = newCardType; + // Two paths: + // 1) Via Config dialog: card not inserted yet + // 2) Snapshot_LoadState_v2(): card already inserted + if (g_CardMgr.QuerySlot(slot) != newCardType) + g_CardMgr.Insert(slot, newCardType); std::string slotText; switch (slot) @@ -139,7 +144,7 @@ void CPropertySheetHelper::SetSlot(UINT slot, SS_CARDTYPE newCardType) case 7: slotText = REGVALUE_SLOT7; break; } - REGSAVE(slotText.c_str(), (DWORD)g_Slot[slot]); + REGSAVE(slotText.c_str(), (DWORD)newCardType); } // Looks like a (bad) C&P from SaveStateSelectImage() @@ -209,7 +214,10 @@ void CPropertySheetHelper::SaveStateUpdate() void CPropertySheetHelper::GetDiskBaseNameWithAWS(std::string & pszFilename) { - const std::string & pDiskName = sg_Disk2Card.GetBaseName(DRIVE_1); + if (g_CardMgr.QuerySlot(SLOT6) != CT_Disk2) + return; + + const std::string & pDiskName = dynamic_cast(g_CardMgr.GetObj(SLOT6))->GetBaseName(DRIVE_1); if (!pDiskName.empty()) { pszFilename = pDiskName + ".aws.yaml"; @@ -445,8 +453,8 @@ void CPropertySheetHelper::SaveCurrentConfig(void) // NB. clone-type is encoded in g_Apple2Type m_ConfigOld.m_Apple2Type = GetApple2Type(); m_ConfigOld.m_CpuType = GetMainCpu(); - m_ConfigOld.m_Slot[4] = g_Slot[4]; - m_ConfigOld.m_Slot[5] = g_Slot[5]; + m_ConfigOld.m_Slot[SLOT4] = g_CardMgr.QuerySlot(SLOT4); + m_ConfigOld.m_Slot[SLOT5] = g_CardMgr.QuerySlot(SLOT5); m_ConfigOld.m_bEnableHDD = HD_CardIsEnabled(); m_ConfigOld.m_bEnableTheFreezesF8Rom = sg_PropertySheet.GetTheFreezesF8Rom(); m_ConfigOld.m_videoRefreshRate = GetVideoRefreshRate(); @@ -464,8 +472,8 @@ void CPropertySheetHelper::RestoreCurrentConfig(void) // NB. clone-type is encoded in g_Apple2Type SetApple2Type(m_ConfigOld.m_Apple2Type); SetMainCpu(m_ConfigOld.m_CpuType); - g_Slot[4] = m_ConfigOld.m_Slot[4]; - g_Slot[5] = m_ConfigOld.m_Slot[5]; + g_CardMgr.Insert(SLOT4, m_ConfigOld.m_Slot[SLOT4]); + g_CardMgr.Insert(SLOT5, m_ConfigOld.m_Slot[SLOT5]); HD_SetEnabled(m_ConfigOld.m_bEnableHDD); sg_PropertySheet.SetTheFreezesF8Rom(m_ConfigOld.m_bEnableTheFreezesF8Rom); SetVideoRefreshRate(m_ConfigOld.m_videoRefreshRate); diff --git a/source/Debugger/Debug.cpp b/source/Debugger/Debug.cpp index 94dc73ee..0d463108 100644 --- a/source/Debugger/Debug.cpp +++ b/source/Debugger/Debug.cpp @@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "DebugDefs.h" #include "../Applewin.h" +#include "../CardManager.h" #include "../CPU.h" #include "../Disk.h" #include "../Frame.h" @@ -3752,6 +3753,11 @@ Update_t CmdDisk ( int nArgs) if (! nArgs) goto _Help; + if (g_CardMgr.QuerySlot(SLOT6) != CT_Disk2) + return ConsoleDisplayError("No DiskII card in slot-6"); + + Disk2InterfaceCard* pDiskCard = dynamic_cast(g_CardMgr.GetObj(SLOT6)); + // check for info command int iParam = 0; FindParam( g_aArgs[ 1 ].sArg, MATCH_EXACT, iParam, _PARAM_DISK_BEGIN, _PARAM_DISK_END ); @@ -3763,13 +3769,13 @@ Update_t CmdDisk ( int nArgs) char buffer[200] = ""; ConsoleBufferPushFormat(buffer, "D%d at T$%s, phase $%s, offset $%X, mask $%02X, extraCycles %.2f, %s", - sg_Disk2Card.GetCurrentDrive() + 1, - sg_Disk2Card.GetCurrentTrackString().c_str(), - sg_Disk2Card.GetCurrentPhaseString().c_str(), - sg_Disk2Card.GetCurrentOffset(), - sg_Disk2Card.GetCurrentLSSBitMask(), - sg_Disk2Card.GetCurrentExtraCycles(), - sg_Disk2Card.GetCurrentState() + pDiskCard->GetCurrentDrive() + 1, + pDiskCard->GetCurrentTrackString().c_str(), + pDiskCard->GetCurrentPhaseString().c_str(), + pDiskCard->GetCurrentOffset(), + pDiskCard->GetCurrentLSSBitMask(), + pDiskCard->GetCurrentExtraCycles(), + pDiskCard->GetCurrentState() ); return ConsoleUpdate(); @@ -3797,7 +3803,7 @@ Update_t CmdDisk ( int nArgs) if (nArgs > 2) goto _Help; - sg_Disk2Card.EjectDisk( iDrive ); + pDiskCard->EjectDisk( iDrive ); FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); } else @@ -3811,7 +3817,7 @@ Update_t CmdDisk ( int nArgs) if (nArgs == 3) bProtect = g_aArgs[ 3 ].nValue ? true : false; - sg_Disk2Card.SetProtect( iDrive, bProtect ); + pDiskCard->SetProtect( iDrive, bProtect ); FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); } else @@ -3822,7 +3828,7 @@ Update_t CmdDisk ( int nArgs) LPCTSTR pDiskName = g_aArgs[ 3 ].sArg; // DISK # "Diskname" - sg_Disk2Card.InsertDisk( iDrive, pDiskName, IMAGE_FORCE_WRITE_PROTECTED, IMAGE_DONT_CREATE ); + pDiskCard->InsertDisk( iDrive, pDiskName, IMAGE_FORCE_WRITE_PROTECTED, IMAGE_DONT_CREATE ); FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); } diff --git a/source/Disk.cpp b/source/Disk.cpp index f30b12bc..39f2b9d0 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -53,7 +53,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // . if false && I/O ReadWrite($C0EC) && drive is spinning, then advance the track buffer's nibble index (to simulate spinning). // Also m_enhanceDisk is persisted to the save-state, so it's an attribute of the DiskII interface card. -Disk2InterfaceCard::Disk2InterfaceCard(void) +Disk2InterfaceCard::Disk2InterfaceCard(void) : + Card(CT_Disk2) { ResetSwitches(); @@ -76,6 +77,12 @@ Disk2InterfaceCard::Disk2InterfaceCard(void) #endif } +Disk2InterfaceCard::~Disk2InterfaceCard(void) +{ + EjectDiskInternal(DRIVE_1); + EjectDiskInternal(DRIVE_2); +} + bool Disk2InterfaceCard::GetEnhanceDisk(void) { return m_enhanceDisk; } void Disk2InterfaceCard::SetEnhanceDisk(bool bEnhanceDisk) { m_enhanceDisk = bEnhanceDisk; } @@ -173,6 +180,9 @@ void Disk2InterfaceCard::SaveLastDiskImage(const int drive) { _ASSERT(drive == DRIVE_1 || drive == DRIVE_2); + if (m_slot != 6) // DiskII cards in other slots don't save image to Registry + return; + if (!m_saveDiskImage) return; @@ -321,7 +331,7 @@ void Disk2InterfaceCard::ReadTrack(const int drive, ULONG uExecutedCycles) //=========================================================================== -void Disk2InterfaceCard::RemoveDisk(const int drive) +void Disk2InterfaceCard::EjectDiskInternal(const int drive) { FloppyDisk* pFloppy = &m_floppyDrive[drive].m_disk; @@ -336,16 +346,24 @@ void Disk2InterfaceCard::RemoveDisk(const int drive) if (pFloppy->m_trackimage) { VirtualFree(pFloppy->m_trackimage, 0, MEM_RELEASE); - pFloppy->m_trackimage = NULL; + pFloppy->m_trackimage = NULL; pFloppy->m_trackimagedata = false; } pFloppy->m_imagename.clear(); pFloppy->m_fullname.clear(); pFloppy->m_strFilenameInZip = ""; +} - SaveLastDiskImage( drive ); - Video_ResetScreenshotCounter( "" ); +void Disk2InterfaceCard::EjectDisk(const int drive) +{ + if (!IsDriveValid(drive)) + return; + + EjectDiskInternal(drive); + + SaveLastDiskImage(drive); + Video_ResetScreenshotCounter(""); } //=========================================================================== @@ -516,10 +534,10 @@ void __stdcall Disk2InterfaceCard::ControlStepper(WORD, WORD address, BYTE, BYTE void Disk2InterfaceCard::Destroy(void) { m_saveDiskImage = false; - RemoveDisk(DRIVE_1); + EjectDisk(DRIVE_1); m_saveDiskImage = false; - RemoveDisk(DRIVE_2); + EjectDisk(DRIVE_2); m_saveDiskImage = true; } @@ -539,16 +557,6 @@ void __stdcall Disk2InterfaceCard::Enable(WORD, WORD address, BYTE, BYTE, ULONG //=========================================================================== -void Disk2InterfaceCard::EjectDisk(const int drive) -{ - if (IsDriveValid(drive)) - { - RemoveDisk(drive); - } -} - -//=========================================================================== - // Return the filename // . Used by Drive Buttons' tooltips const std::string & Disk2InterfaceCard::GetFullDiskFilename(const int drive) @@ -597,7 +605,7 @@ ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFil FloppyDisk* pFloppy = &pDrive->m_disk; if (pFloppy->m_imagehandle) - RemoveDisk(drive); + EjectDisk(drive); // Reset the disk's attributes, but preserve the drive's attributes (GH#138/Platoon, GH#640) // . Changing the disk (in the drive) doesn't affect the drive's attributes. @@ -638,7 +646,7 @@ ImageError_e Disk2InterfaceCard::InsertDisk(const int drive, LPCTSTR pszImageFil int nRes = MessageBox(g_hFrameWindow, szText, TEXT("Multi-Zip Warning"), MB_ICONWARNING | MB_YESNO | MB_SETFOREGROUND); if (nRes == IDNO) { - RemoveDisk(drive); + EjectDisk(drive); Error = eIMAGE_ERROR_REJECTED_MULTI_ZIP; } } @@ -1374,7 +1382,7 @@ void Disk2InterfaceCard::DumpTrackWOZ(FloppyDisk floppy) // pass a copy of m_flo //=========================================================================== -void Disk2InterfaceCard::Reset(const bool bIsPowerCycle/*=false*/) +void Disk2InterfaceCard::Reset(const bool bIsPowerCycle) { // RESET forces all switches off (UTAIIe Table 9.1) ResetSwitches(); @@ -1998,7 +2006,7 @@ void Disk2InterfaceCard::LoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, U bool Disk2InterfaceCard::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) { - if (slot != 6) // fixme + if (slot != 5 && slot != 6) // fixme throw std::string("Card: wrong slot"); if (version < 1 || version > kUNIT_VERSION) diff --git a/source/Disk.h b/source/Disk.h index 2122a1c1..85183605 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -23,12 +23,11 @@ along with AppleWin; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "Card.h" #include "DiskLog.h" #include "DiskFormatTrack.h" #include "DiskImage.h" -extern class Disk2InterfaceCard sg_Disk2Card; - enum Drive_e { DRIVE_1 = 0, @@ -118,11 +117,14 @@ public: FloppyDisk m_disk; }; -class Disk2InterfaceCard +class Disk2InterfaceCard : public Card { public: Disk2InterfaceCard(void); - virtual ~Disk2InterfaceCard(void){} + virtual ~Disk2InterfaceCard(void); + + virtual void Init(void) {}; + virtual void Reset(const bool powerCycle); void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot); void Destroy(void); // no, doesn't "destroy" the disk image. DiskIIManagerShutdown() @@ -140,7 +142,6 @@ public: bool IsConditionForFullSpeed(void); void NotifyInvalidImage(const int drive, LPCTSTR pszImageFilename, const ImageError_e Error); - void Reset(const bool bIsPowerCycle=false); bool GetProtect(const int drive); void SetProtect(const int drive, const bool bWriteProtect); int GetCurrentDrive(void); @@ -157,7 +158,7 @@ public: void UpdateDriveState(DWORD cycles); bool DriveSwap(void); - std::string GetSnapshotCardName(void); + static std::string GetSnapshotCardName(void); void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); @@ -178,9 +179,9 @@ private: void CheckSpinning(const ULONG uExecutedCycles); Disk_Status_e GetDriveLightStatus(const int drive); bool IsDriveValid(const int drive); + void EjectDiskInternal(const int drive); void AllocTrack(const int drive); void ReadTrack(const int drive, ULONG uExecutedCycles); - void RemoveDisk(const int drive); void WriteTrack(const int drive); const std::string & DiskGetFullPathName(const int drive); void ResetLogicStateSequencer(void); diff --git a/source/Disk2CardManager.cpp b/source/Disk2CardManager.cpp new file mode 100644 index 00000000..049f0fdb --- /dev/null +++ b/source/Disk2CardManager.cpp @@ -0,0 +1,120 @@ +/* +AppleWin : An Apple //e emulator for Windows + +Copyright (C) 1994-1996, Michael O'Brien +Copyright (C) 1999-2001, Oliver Schmidt +Copyright (C) 2002-2005, Tom Charlesworth +Copyright (C) 2006-2019, Tom Charlesworth, Michael Pohoreski, Nick Westgate + +AppleWin is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +AppleWin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with AppleWin; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* Description: Disk2 Card Manager + * + * Author: Various + * + */ + +#include "StdAfx.h" + +#include "AppleWin.h" +#include "CardManager.h" +#include "Disk.h" +#include "Disk2CardManager.h" + +bool Disk2CardManager::IsConditionForFullSpeed(void) +{ + for (UINT i = 0; i < NUM_SLOTS; i++) + { + if (g_CardMgr.QuerySlot(i) == CT_Disk2) + { + if (dynamic_cast(g_CardMgr.GetObj(i))->IsConditionForFullSpeed()) + return true; // if any card is true then the condition for full-speed is true + } + } + + return false; +} + +void Disk2CardManager::UpdateDriveState(UINT cycles) +{ + for (UINT i = 0; i < NUM_SLOTS; i++) + { + if (g_CardMgr.QuerySlot(i) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(i))->UpdateDriveState(cycles); + } + } +} + +void Disk2CardManager::Reset(const bool powerCycle /*=false*/) +{ + for (UINT i = 0; i < NUM_SLOTS; i++) + { + if (g_CardMgr.QuerySlot(i) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(i))->Reset(powerCycle); + } + } +} + +bool Disk2CardManager::GetEnhanceDisk(void) +{ + for (UINT i = 0; i < NUM_SLOTS; i++) + { + if (g_CardMgr.QuerySlot(i) == CT_Disk2) + { + // All Disk2 cards should have the same setting, so just return the state of the first card + return dynamic_cast(g_CardMgr.GetObj(i))->GetEnhanceDisk(); + } + } + return false; +} + +void Disk2CardManager::SetEnhanceDisk(bool enhanceDisk) +{ + for (UINT i = 0; i < NUM_SLOTS; i++) + { + if (g_CardMgr.QuerySlot(i) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(i))->SetEnhanceDisk(enhanceDisk); + } + } +} + +void Disk2CardManager::LoadLastDiskImage(void) +{ + for (UINT i = 0; i < NUM_SLOTS; i++) + { + if (i != SLOT6) continue; // FIXME + + if (g_CardMgr.QuerySlot(i) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(i))->LoadLastDiskImage(DRIVE_1); + dynamic_cast(g_CardMgr.GetObj(i))->LoadLastDiskImage(DRIVE_2); + } + } +} + +void Disk2CardManager::Destroy(void) +{ + for (UINT i = 0; i < NUM_SLOTS; i++) + { + if (g_CardMgr.QuerySlot(i) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(i))->Destroy(); + } + } +} diff --git a/source/Disk2CardManager.h b/source/Disk2CardManager.h new file mode 100644 index 00000000..5f8769a0 --- /dev/null +++ b/source/Disk2CardManager.h @@ -0,0 +1,16 @@ +#pragma once + +class Disk2CardManager +{ +public: + Disk2CardManager(void) {} + ~Disk2CardManager(void) {} + + bool IsConditionForFullSpeed(void); + void UpdateDriveState(UINT cycles); + void Reset(const bool powerCycle = false); + bool GetEnhanceDisk(void); + void SetEnhanceDisk(bool enhanceDisk); + void LoadLastDiskImage(void); + void Destroy(void); +}; diff --git a/source/Frame.cpp b/source/Frame.cpp index 6d8cf309..2bbe2d14 100644 --- a/source/Frame.cpp +++ b/source/Frame.cpp @@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include "Applewin.h" +#include "CardManager.h" #include "CPU.h" #include "Disk.h" #include "DiskImage.h" @@ -170,6 +171,8 @@ static int g_win_fullscreen_offsety = 0; static bool g_bFrameActive = false; +static std::string driveTooltip; + // __ Prototypes __________________________________________________________________________________ void DrawCrosshairs (int x, int y); void UpdateMouseInAppleViewport(int iOutOfBoundsX, int iOutOfBoundsY, int x=0, int y=0); @@ -321,10 +324,12 @@ static void FrameShowCursor(BOOL bShow) // . AppleWin's main window is activated/deactivated static void RevealCursor() { - if (!sg_Mouse.IsActiveAndEnabled()) + CMouseInterface* pMouseCard = g_CardMgr.GetMouseCard(); + + if (!pMouseCard || !pMouseCard->IsActiveAndEnabled()) return; - sg_Mouse.SetEnabled(false); + pMouseCard->SetEnabled(false); FrameShowCursor(TRUE); @@ -346,7 +351,7 @@ static void FullScreenRevealCursor(void) if (!g_bIsFullScreen) return; - if (sg_Mouse.IsActive()) + if (g_CardMgr.IsMouseCardInstalled()) return; if (!g_bUsingCursor && !g_bShowingCursor) @@ -508,7 +513,11 @@ static void DrawButton (HDC passdc, int number) { SetTextColor(dc,RGB(0,0,0)); SetTextAlign(dc,TA_CENTER | TA_TOP); SetBkMode(dc,TRANSPARENT); - LPCTSTR pszBaseName = sg_Disk2Card.GetBaseName(number-BTN_DRIVE1).c_str(); + + LPCTSTR pszBaseName = (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + ? dynamic_cast(g_CardMgr.GetObj(SLOT6))->GetBaseName(number-BTN_DRIVE1).c_str() + : ""; + ExtTextOut(dc,x+offset+22,rect.top,ETO_CLIPPED,&rect, pszBaseName, MIN(8,_tcslen(pszBaseName)), @@ -696,12 +705,23 @@ void SetFullScreenShowSubunitStatus(bool bShow) //=========================================================================== void FrameDrawDiskLEDS( HDC passdc ) { - Disk_Status_e eDrive1Status; - Disk_Status_e eDrive2Status; - sg_Disk2Card.GetLightStatus(&eDrive1Status, &eDrive2Status); + g_eStatusDrive1 = DISK_STATUS_OFF; + g_eStatusDrive2 = DISK_STATUS_OFF; - g_eStatusDrive1 = eDrive1Status; - g_eStatusDrive2 = eDrive2Status; + // Slot6 drive takes priority unless it's off: + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + dynamic_cast(g_CardMgr.GetObj(SLOT6))->GetLightStatus(&g_eStatusDrive1, &g_eStatusDrive2); + + // Slot5: + { + Disk_Status_e eDrive1StatusSlot5 = DISK_STATUS_OFF; + Disk_Status_e eDrive2StatusSlot5 = DISK_STATUS_OFF; + if (g_CardMgr.QuerySlot(SLOT5) == CT_Disk2) + dynamic_cast(g_CardMgr.GetObj(SLOT5))->GetLightStatus(&eDrive1StatusSlot5, &eDrive2StatusSlot5); + + if (g_eStatusDrive1 == DISK_STATUS_OFF) g_eStatusDrive1 = eDrive1StatusSlot5; + if (g_eStatusDrive2 == DISK_STATUS_OFF) g_eStatusDrive2 = eDrive2StatusSlot5; + } // Draw Track/Sector FrameReleaseDC(); @@ -720,17 +740,17 @@ void FrameDrawDiskLEDS( HDC passdc ) SetBkColor(dc,RGB(0,0,0)); SetTextAlign(dc,TA_LEFT | TA_TOP); - SetTextColor(dc, g_aDiskFullScreenColorsLED[ eDrive1Status ] ); + SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive1] ); TextOut(dc,x+ 3,y+2,TEXT("1"),1); - SetTextColor(dc, g_aDiskFullScreenColorsLED[ eDrive2Status ] ); + SetTextColor(dc, g_aDiskFullScreenColorsLED[g_eStatusDrive2] ); TextOut(dc,x+13,y+2,TEXT("2"),1); } else { RECT rDiskLed = {0,0,8,8}; - DrawBitmapRect(dc,x+12,y+6,&rDiskLed,g_hDiskWindowedLED[eDrive1Status]); - DrawBitmapRect(dc,x+31,y+6,&rDiskLed,g_hDiskWindowedLED[eDrive2Status]); + DrawBitmapRect(dc,x+12,y+6,&rDiskLed,g_hDiskWindowedLED[g_eStatusDrive1]); + DrawBitmapRect(dc,x+31,y+6,&rDiskLed,g_hDiskWindowedLED[g_eStatusDrive2]); } } @@ -751,10 +771,14 @@ void FrameDrawDiskStatus( HDC passdc ) // Track $B7EC LC1 $D356 // Sector $B7ED LC1 $D357 // RWTS LC1 $D300 - int nActiveFloppy = sg_Disk2Card.GetCurrentDrive(); - int nDisk1Track = sg_Disk2Card.GetTrack(DRIVE_1); - int nDisk2Track = sg_Disk2Card.GetTrack(DRIVE_2); + if (g_CardMgr.QuerySlot(SLOT6) != CT_Disk2) + return; + + Disk2InterfaceCard* pDisk2Card = dynamic_cast(g_CardMgr.GetObj(SLOT6)); + int nActiveFloppy = pDisk2Card->GetCurrentDrive(); + int nDisk1Track = pDisk2Card->GetTrack(DRIVE_1); + int nDisk2Track = pDisk2Card->GetTrack(DRIVE_2); // Probe known OS's for Track/Sector int isProDOS = mem[ 0xBF00 ] == 0x4C; @@ -1099,12 +1123,13 @@ LRESULT CALLBACK FrameWndProc ( Snapshot_Shutdown(); DebugDestroy(); if (!g_bRestart) { - sg_Disk2Card.Destroy(); + g_CardMgr.GetDisk2CardMgr().Destroy(); ImageDestroy(); HD_Destroy(); } PrintDestroy(); - sg_SSC.CommDestroy(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommDestroy(); CpuDestroy(); MemDestroy(); SpkrDestroy(); @@ -1153,61 +1178,70 @@ LRESULT CALLBACK FrameWndProc ( break; } - case WM_DDE_EXECUTE: { - LogFileOutput("WM_DDE_EXECUTE\n"); - LPTSTR filename = (LPTSTR)GlobalLock((HGLOBAL)lparam); -//MessageBox( g_hFrameWindow, filename, "DDE Exec", MB_OK ); - ImageError_e Error = sg_Disk2Card.InsertDisk(DRIVE_1, filename, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE); - if (Error == eIMAGE_ERROR_NONE) - { - if (!g_bIsFullScreen) - DrawButton((HDC)0,BTN_DRIVE1); + case WM_DDE_EXECUTE: + { + LogFileOutput("WM_DDE_EXECUTE\n"); + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + { + Disk2InterfaceCard* pDisk2Card = dynamic_cast(g_CardMgr.GetObj(SLOT6)); + LPTSTR filename = (LPTSTR)GlobalLock((HGLOBAL)lparam); + ImageError_e Error = pDisk2Card->InsertDisk(DRIVE_1, filename, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE); + if (Error == eIMAGE_ERROR_NONE) + { + if (!g_bIsFullScreen) + DrawButton((HDC)0,BTN_DRIVE1); - PostMessage(window, WM_USER_BOOT, 0, 0); - } - else - { - sg_Disk2Card.NotifyInvalidImage(DRIVE_1, filename, Error); - } - GlobalUnlock((HGLOBAL)lparam); - LogFileOutput("WM_DDE_EXECUTE (done)\n"); - break; - } + PostMessage(window, WM_USER_BOOT, 0, 0); + } + else + { + pDisk2Card->NotifyInvalidImage(DRIVE_1, filename, Error); + } + } + GlobalUnlock((HGLOBAL)lparam); + LogFileOutput("WM_DDE_EXECUTE (done)\n"); + break; + } case WM_DISPLAYCHANGE: VideoReinitialize(); break; - case WM_DROPFILES: { - TCHAR filename[MAX_PATH]; - DragQueryFile((HDROP)wparam,0,filename,sizeof(filename)); - POINT point; - DragQueryPoint((HDROP)wparam,&point); - RECT rect; - rect.left = buttonx; - rect.right = rect.left+BUTTONCX+1; - rect.top = buttony+BTN_DRIVE2*BUTTONCY+1; - rect.bottom = rect.top+BUTTONCY; - const int iDrive = PtInRect(&rect,point) ? DRIVE_2 : DRIVE_1; - ImageError_e Error = sg_Disk2Card.InsertDisk(iDrive, filename, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE); - if (Error == eIMAGE_ERROR_NONE) - { - if (!g_bIsFullScreen) - DrawButton((HDC)0,PtInRect(&rect,point) ? BTN_DRIVE2 : BTN_DRIVE1); - rect.top = buttony+BTN_DRIVE1*BUTTONCY+1; - if (!PtInRect(&rect,point)) + case WM_DROPFILES: + { + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) { - SetForegroundWindow(window); - ProcessButtonClick(BTN_RUN); - } - } - else - { - sg_Disk2Card.NotifyInvalidImage(iDrive, filename, Error); - } - DragFinish((HDROP)wparam); - break; - } + Disk2InterfaceCard* pDisk2Card = dynamic_cast(g_CardMgr.GetObj(SLOT6)); + TCHAR filename[MAX_PATH]; + DragQueryFile((HDROP)wparam,0,filename,sizeof(filename)); + POINT point; + DragQueryPoint((HDROP)wparam,&point); + RECT rect; + rect.left = buttonx; + rect.right = rect.left+BUTTONCX+1; + rect.top = buttony+BTN_DRIVE2*BUTTONCY+1; + rect.bottom = rect.top+BUTTONCY; + const int iDrive = PtInRect(&rect,point) ? DRIVE_2 : DRIVE_1; + ImageError_e Error = pDisk2Card->InsertDisk(iDrive, filename, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE); + if (Error == eIMAGE_ERROR_NONE) + { + if (!g_bIsFullScreen) + DrawButton((HDC)0,PtInRect(&rect,point) ? BTN_DRIVE2 : BTN_DRIVE1); + rect.top = buttony+BTN_DRIVE1*BUTTONCY+1; + if (!PtInRect(&rect,point)) + { + SetForegroundWindow(window); + ProcessButtonClick(BTN_RUN); + } + } + else + { + pDisk2Card->NotifyInvalidImage(iDrive, filename, Error); + } + } + DragFinish((HDROP)wparam); + break; + } // @see: http://answers.google.com/answers/threadview?id=133059 // Win32 doesn't pass the PrintScreen key via WM_CHAR @@ -1492,7 +1526,7 @@ LRESULT CALLBACK FrameWndProc ( DrawButton((HDC)0,buttonactive); SetCapture(window); } - else if (g_bUsingCursor && !sg_Mouse.IsActive()) + else if (g_bUsingCursor && !g_CardMgr.IsMouseCardInstalled()) { if (wparam & (MK_CONTROL | MK_SHIFT)) { @@ -1507,7 +1541,7 @@ LRESULT CALLBACK FrameWndProc ( { SetUsingCursor(TRUE); } - else if (sg_Mouse.IsActive()) + else if (g_CardMgr.IsMouseCardInstalled()) { if (wparam & (MK_CONTROL | MK_SHIFT)) { @@ -1515,21 +1549,26 @@ LRESULT CALLBACK FrameWndProc ( } else if (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING) { - if (!sg_Mouse.IsEnabled()) - { - sg_Mouse.SetEnabled(true); + CMouseInterface* pMouseCard = g_CardMgr.GetMouseCard(); - POINT Point; - GetCursorPos(&Point); - ScreenToClient(g_hFrameWindow, &Point); - const int iOutOfBoundsX=0, iOutOfBoundsY=0; - UpdateMouseInAppleViewport(iOutOfBoundsX, iOutOfBoundsY, Point.x, Point.y); - - // Don't call SetButton() when 1st enabled (else get the confusing action of both enabling & an Apple mouse click) - } - else + if (pMouseCard) { - sg_Mouse.SetButton(BUTTON0, BUTTON_DOWN); + if (!pMouseCard->IsEnabled()) + { + pMouseCard->SetEnabled(true); + + POINT Point; + GetCursorPos(&Point); + ScreenToClient(g_hFrameWindow, &Point); + const int iOutOfBoundsX=0, iOutOfBoundsY=0; + UpdateMouseInAppleViewport(iOutOfBoundsX, iOutOfBoundsY, Point.x, Point.y); + + // Don't call SetButton() when 1st enabled (else get the confusing action of both enabling & an Apple mouse click) + } + else + { + pMouseCard->SetButton(BUTTON0, BUTTON_DOWN); + } } } } @@ -1552,13 +1591,13 @@ LRESULT CALLBACK FrameWndProc ( } buttonactive = -1; } - else if (g_bUsingCursor && !sg_Mouse.IsActive()) + else if (g_bUsingCursor && !g_CardMgr.IsMouseCardInstalled()) { JoySetButton(BUTTON0, BUTTON_UP); } - else if (sg_Mouse.IsActive()) + else if (g_CardMgr.IsMouseCardInstalled()) { - sg_Mouse.SetButton(BUTTON0, BUTTON_UP); + g_CardMgr.GetMouseCard()->SetButton(BUTTON0, BUTTON_UP); } RelayEvent(WM_LBUTTONUP,wparam,lparam); break; @@ -1586,12 +1625,12 @@ LRESULT CALLBACK FrameWndProc ( if (buttonover != -1) DrawButton((HDC)0,buttonover); } - else if (g_bUsingCursor && !sg_Mouse.IsActive()) + else if (g_bUsingCursor && !g_CardMgr.IsMouseCardInstalled()) { DrawCrosshairs(x,y); JoySetPosition(x-viewportx-2, g_nViewportCX-4, y-viewporty-2, g_nViewportCY-4); } - else if (sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING)) + else if (g_CardMgr.IsMouseCardInstalled() && g_CardMgr.GetMouseCard()->IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING)) { if (g_bLastCursorInAppleViewport) break; @@ -1624,7 +1663,7 @@ LRESULT CALLBACK FrameWndProc ( if (wparam == IDEVENT_TIMER_MOUSE) { // NB. Need to check /g_bAppActive/ since WM_TIMER events still occur after AppleWin app has lost focus - if (g_bAppActive && sg_Mouse.IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING)) + if (g_bAppActive && g_CardMgr.IsMouseCardInstalled() && g_CardMgr.GetMouseCard()->IsActiveAndEnabled() && (g_nAppMode == MODE_RUNNING || g_nAppMode == MODE_STEPPING)) { if (!g_bLastCursorInAppleViewport) break; @@ -1635,7 +1674,7 @@ LRESULT CALLBACK FrameWndProc ( long dX,dY; if (DIMouse::ReadImmediateData(&dX, &dY) == S_OK) - sg_Mouse.SetPositionRel(dX, dY, &iOutOfBoundsX, &iOutOfBoundsY); + g_CardMgr.GetMouseCard()->SetPositionRel(dX, dY, &iOutOfBoundsX, &iOutOfBoundsY); UpdateMouseInAppleViewport(iOutOfBoundsX, iOutOfBoundsY); } @@ -1643,7 +1682,7 @@ LRESULT CALLBACK FrameWndProc ( else if (wparam == IDEVENT_TIMER_100MSEC) // GH#504 { if (g_bIsFullScreen - && !sg_Mouse.IsActive() // Don't interfere if there's a mousecard present! + && !g_CardMgr.IsMouseCardInstalled() // Don't interfere if there's a mousecard present! && !g_bUsingCursor // Using mouse for joystick emulation (or mousecard restricted to window) && g_bShowingCursor && g_bFrameActive) // Frame inactive when eg. Config or 'Select Disk Image' dialogs are opened @@ -1677,11 +1716,34 @@ LRESULT CALLBACK FrameWndProc ( break; case WM_NOTIFY: // Tooltips for Drive buttons - if(((LPNMTTDISPINFO)lparam)->hdr.hwndFrom == tooltipwindow && - ((LPNMTTDISPINFO)lparam)->hdr.code == TTN_GETDISPINFO) - ((LPNMTTDISPINFO)lparam)->lpszText = - (LPTSTR)sg_Disk2Card.GetFullDiskFilename(((LPNMTTDISPINFO)lparam)->hdr.idFrom).c_str(); - break; + if (((LPNMTTDISPINFO)lparam)->hdr.hwndFrom == tooltipwindow && ((LPNMTTDISPINFO)lparam)->hdr.code == TTN_GETDISPINFO) + { + LPNMTTDISPINFO pInfo = (LPNMTTDISPINFO)lparam; + SendMessage(pInfo->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, 0, 150); + + Disk2InterfaceCard *pDisk2Slot5 = NULL, *pDisk2Slot6 = NULL; + + if (g_CardMgr.QuerySlot(SLOT5) == CT_Disk2) + pDisk2Slot5 = dynamic_cast(g_CardMgr.GetObj(SLOT5)); + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + pDisk2Slot6 = dynamic_cast(g_CardMgr.GetObj(SLOT6)); + + std::string slot5 = pDisk2Slot5 ? pDisk2Slot5->GetFullDiskFilename(((LPNMTTDISPINFO)lparam)->hdr.idFrom) : ""; + std::string slot6 = pDisk2Slot6 ? pDisk2Slot6->GetFullDiskFilename(((LPNMTTDISPINFO)lparam)->hdr.idFrom) : ""; + + if (pDisk2Slot5) + { + if (slot6.empty()) slot6 = ""; + if (slot5.empty()) slot5 = ""; + slot6 = std::string("Slot6: ") + slot6; + slot5 = std::string("Slot5: ") + slot5; + } + + std::string join = (!slot6.empty() && !slot5.empty()) ? "\r\n" : ""; + driveTooltip = slot6 + join + slot5; + ((LPNMTTDISPINFO)lparam)->lpszText = (LPTSTR)driveTooltip.c_str(); + } + break; case WM_PAINT: if (GetUpdateRect(window,NULL,0)) { @@ -1751,10 +1813,10 @@ LRESULT CALLBACK FrameWndProc ( } } - if (g_bUsingCursor && !sg_Mouse.IsActive()) + if (g_bUsingCursor && !g_CardMgr.IsMouseCardInstalled()) JoySetButton(BUTTON1, (message == WM_RBUTTONDOWN) ? BUTTON_DOWN : BUTTON_UP); - else if (sg_Mouse.IsActive()) - sg_Mouse.SetButton(BUTTON1, (message == WM_RBUTTONDOWN) ? BUTTON_DOWN : BUTTON_UP); + else if (g_CardMgr.IsMouseCardInstalled()) + g_CardMgr.GetMouseCard()->SetButton(BUTTON1, (message == WM_RBUTTONDOWN) ? BUTTON_DOWN : BUTTON_UP); RelayEvent(message,wparam,lparam); break; @@ -1853,11 +1915,13 @@ LRESULT CALLBACK FrameWndProc ( case WSAECONNRESET: case WSAENOTCONN: case WSAETIMEDOUT: - sg_SSC.CommTcpSerialClose(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommTcpSerialClose(); break; default: - sg_SSC.CommTcpSerialCleanup(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommTcpSerialCleanup(); break; } } @@ -1867,15 +1931,18 @@ LRESULT CALLBACK FrameWndProc ( switch(wSelectEvent) { case FD_ACCEPT: - sg_SSC.CommTcpSerialAccept(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommTcpSerialAccept(); break; case FD_CLOSE: - sg_SSC.CommTcpSerialClose(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommTcpSerialClose(); break; case FD_READ: - sg_SSC.CommTcpSerialReceive(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommTcpSerialReceive(); break; } } @@ -1990,7 +2057,9 @@ static void ProcessButtonClick(int button, bool bFromButtonUI /*=false*/) if (g_nAppMode == MODE_LOGO) { - sg_Disk2Card.Boot(); + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + dynamic_cast(g_CardMgr.GetObj(SLOT6))->Boot(); + LogFileTimeUntilFirstKeyReadReset(); g_nAppMode = MODE_RUNNING; } @@ -2013,14 +2082,20 @@ static void ProcessButtonClick(int button, bool bFromButtonUI /*=false*/) case BTN_DRIVE1: case BTN_DRIVE2: - sg_Disk2Card.UserSelectNewDiskImage(button-BTN_DRIVE1); - if (!g_bIsFullScreen) - DrawButton((HDC)0,button); - break; + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(SLOT6))->UserSelectNewDiskImage(button-BTN_DRIVE1); + if (!g_bIsFullScreen) + DrawButton((HDC)0,button); + } + break; case BTN_DRIVESWAP: - sg_Disk2Card.DriveSwap(); - break; + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(SLOT6))->DriveSwap(); + } + break; case BTN_FULLSCR: KeybUpdateCtrlShiftStatus(); @@ -2074,6 +2149,11 @@ static void ProcessButtonClick(int button, bool bFromButtonUI /*=false*/) void ProcessDiskPopupMenu(HWND hwnd, POINT pt, const int iDrive) { + if (g_CardMgr.QuerySlot(SLOT6) != CT_Disk2) + return; + + Disk2InterfaceCard* pDisk2Card = dynamic_cast(g_CardMgr.GetObj(SLOT6)); + // This is the default installation path of CiderPress. // It shall not be left blank, otherwise an explorer window will be open. TCHAR PathToCiderPress[MAX_PATH]; @@ -2087,7 +2167,7 @@ void ProcessDiskPopupMenu(HWND hwnd, POINT pt, const int iDrive) //TODO: A directory is open if an empty path to CiderPress is set. This has to be fixed. std::string filename1= "\""; - filename1.append( sg_Disk2Card.GetFullName(iDrive) ); + filename1.append( pDisk2Card->GetFullName(iDrive) ); filename1.append("\""); std::string sFileNameEmpty = "\""; sFileNameEmpty.append("\""); @@ -2109,16 +2189,16 @@ void ProcessDiskPopupMenu(HWND hwnd, POINT pt, const int iDrive) // Check menu depending on current floppy protection { int iMenuItem = ID_DISKMENU_WRITEPROTECTION_OFF; - if (sg_Disk2Card.GetProtect( iDrive )) + if (pDisk2Card->GetProtect( iDrive )) iMenuItem = ID_DISKMENU_WRITEPROTECTION_ON; CheckMenuItem(hmenu, iMenuItem, MF_CHECKED); } - if (sg_Disk2Card.IsDriveEmpty(iDrive)) + if (pDisk2Card->IsDriveEmpty(iDrive)) EnableMenuItem(hmenu, ID_DISKMENU_EJECT, MF_GRAYED); - if (sg_Disk2Card.IsDiskImageWriteProtected(iDrive)) + if (pDisk2Card->IsDiskImageWriteProtected(iDrive)) { // If image-file is read-only (or a gzip) then disable these menu items EnableMenuItem(hmenu, ID_DISKMENU_WRITEPROTECTION_ON, MF_GRAYED); @@ -2134,13 +2214,13 @@ void ProcessDiskPopupMenu(HWND hwnd, POINT pt, const int iDrive) , hwnd, NULL ); if (iCommand == ID_DISKMENU_EJECT) - sg_Disk2Card.EjectDisk( iDrive ); + pDisk2Card->EjectDisk( iDrive ); else if (iCommand == ID_DISKMENU_WRITEPROTECTION_ON) - sg_Disk2Card.SetProtect( iDrive, true ); + pDisk2Card->SetProtect( iDrive, true ); else if (iCommand == ID_DISKMENU_WRITEPROTECTION_OFF) - sg_Disk2Card.SetProtect( iDrive, false ); + pDisk2Card->SetProtect( iDrive, false ); else if (iCommand == ID_DISKMENU_SENDTO_CIDERPRESS) { @@ -2149,7 +2229,7 @@ void ProcessDiskPopupMenu(HWND hwnd, POINT pt, const int iDrive) "Please install CiderPress.\n" "Otherwise set the path to CiderPress from Configuration->Disk."; - sg_Disk2Card.FlushCurrentTrack(iDrive); + pDisk2Card->FlushCurrentTrack(iDrive); //if(!filename1.compare("\"\"") == false) //Do not use this, for some reason it does not work!!! if(!filename1.compare(sFileNameEmpty) ) @@ -2211,21 +2291,24 @@ void RelayEvent (UINT message, WPARAM wparam, LPARAM lparam) { // todo: consolidate CtrlReset() and ResetMachineState() void ResetMachineState () { - sg_Disk2Card.Reset(true); + g_CardMgr.GetDisk2CardMgr().Reset(true); HD_Reset(); g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted MemReset(); // calls CpuInitialize() PravetsReset(); - sg_Disk2Card.Boot(); + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + dynamic_cast(g_CardMgr.GetObj(SLOT6))->Boot(); VideoResetState(); KeybReset(); - sg_SSC.CommReset(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommReset(); PrintReset(); JoyReset(); MB_Reset(); SpkrReset(); - sg_Mouse.Reset(); + if (g_CardMgr.IsMouseCardInstalled()) + g_CardMgr.GetMouseCard()->Reset(); SetActiveCpu( GetMainCpu() ); #ifdef USE_SPEECH_API g_Speech.Reset(); @@ -2256,12 +2339,14 @@ void CtrlReset() } PravetsReset(); - sg_Disk2Card.Reset(); + g_CardMgr.GetDisk2CardMgr().Reset(); HD_Reset(); KeybReset(); - sg_SSC.CommReset(); + if (g_CardMgr.IsSSCInstalled()) + g_CardMgr.GetSSC()->CommReset(); MB_Reset(); - sg_Mouse.Reset(); // Deassert any pending IRQs - GH#514 + if (g_CardMgr.IsMouseCardInstalled()) + g_CardMgr.GetMouseCard()->Reset(); // Deassert any pending IRQs - GH#514 #ifdef USE_SPEECH_API g_Speech.Reset(); #endif @@ -2667,12 +2752,16 @@ static bool FileExists(std::string strFilename) // . UpdateMouseInAppleViewport() is called and inside Apple screen void FrameSetCursorPosByMousePos() { +// _ASSERT(g_CardMgr.IsMouseCardInstalled()); // CMouseInterface::ctor calls this function, ie. before g_CardMgr::m_pMouseCard is setup + if (!g_CardMgr.IsMouseCardInstalled()) + return; + if (!g_hFrameWindow || g_bShowingCursor) return; int iX, iMinX, iMaxX; int iY, iMinY, iMaxY; - sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY); + g_CardMgr.GetMouseCard()->GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY); float fScaleX = (float)(iX-iMinX) / ((float)(iMaxX-iMinX)); float fScaleY = (float)(iY-iMinY) / ((float)(iMaxY-iMinY)); @@ -2702,13 +2791,17 @@ void FrameSetCursorPosByMousePos() // . NB. Not called when leaving & mouse clipped to Apple screen area static void FrameSetCursorPosByMousePos(int x, int y, int dx, int dy, bool bLeavingAppleScreen) { + _ASSERT(g_CardMgr.IsMouseCardInstalled()); + if (!g_CardMgr.IsMouseCardInstalled()) + return; + // char szDbg[200]; if (!g_hFrameWindow || (g_bShowingCursor && bLeavingAppleScreen) || (!g_bShowingCursor && !bLeavingAppleScreen)) return; int iX, iMinX, iMaxX; int iY, iMinY, iMaxY; - sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY); + g_CardMgr.GetMouseCard()->GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY); if (bLeavingAppleScreen) { @@ -2746,7 +2839,7 @@ static void FrameSetCursorPosByMousePos(int x, int y, int dx, int dy, bool bLeav int iAppleX = iMinX + (int)(fScaleX * (float)(iMaxX-iMinX)); int iAppleY = iMinY + (int)(fScaleY * (float)(iMaxY-iMinY)); - sg_Mouse.SetCursorPos(iAppleX, iAppleY); // Set new entry position + g_CardMgr.GetMouseCard()->SetCursorPos(iAppleX, iAppleY); // Set new entry position // Dump initial deltas (otherwise can get big deltas since last read when entering Apple screen area) DIMouse::ReadImmediateData(); @@ -2755,12 +2848,16 @@ static void FrameSetCursorPosByMousePos(int x, int y, int dx, int dy, bool bLeav static void DrawCrosshairsMouse() { + _ASSERT(g_CardMgr.IsMouseCardInstalled()); + if (!g_CardMgr.IsMouseCardInstalled()) + return; + if (!sg_PropertySheet.GetMouseShowCrosshair()) return; int iX, iMinX, iMaxX; int iY, iMinY, iMaxY; - sg_Mouse.GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY); + g_CardMgr.GetMouseCard()->GetXY(iX, iMinX, iMaxX, iY, iMinY, iMaxY); _ASSERT(iMinX == 0 && iMinY == 0); float fScaleX = (float)(iX-iMinX) / ((float)(iMaxX-iMinX)); diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index adadcbd6..3ba8af50 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "Applewin.h" +#include "CardManager.h" #include "CPU.h" #include "DiskImage.h" // ImageError_e, Disk_Status_e #include "DiskImageHelper.h" @@ -276,7 +277,11 @@ void HD_SetEnabled(const bool bEnabled) return; g_bHD_Enabled = bEnabled; - g_Slot[7] = bEnabled ? CT_GenericHDD : CT_Empty; + + if (bEnabled) + g_CardMgr.Insert(SLOT7, CT_GenericHDD); + else + g_CardMgr.Remove(SLOT7); #if 0 // FIXME: For LoadConfiguration(), g_uSlot=7 (see definition at start of file) diff --git a/source/LanguageCard.cpp b/source/LanguageCard.cpp index f39a4141..c6679dbd 100644 --- a/source/LanguageCard.cpp +++ b/source/LanguageCard.cpp @@ -38,9 +38,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA const UINT LanguageCardUnit::kMemModeInitialState = MF_BANK2 | MF_WRITERAM; // !INTCXROM -LanguageCardUnit::LanguageCardUnit(void) : - m_uLastRamWrite(0), - m_type(CT_LanguageCardIIe) +LanguageCardUnit::LanguageCardUnit(SS_CARDTYPE type/*=CT_LanguageCardIIe*/) : + Card(type), + m_uLastRamWrite(0) { SetMemMainLanguageCard(NULL, true); } @@ -136,10 +136,10 @@ bool LanguageCardUnit::IsOpcodeRMWabs(WORD addr) //------------------------------------- -LanguageCardSlot0::LanguageCardSlot0(void) +LanguageCardSlot0::LanguageCardSlot0(SS_CARDTYPE type/*=CT_LanguageCard*/) + : LanguageCardUnit(type) { - m_type = CT_LanguageCard; - m_pMemory = (LPBYTE) VirtualAlloc(NULL, kMemBankSize, MEM_COMMIT, PAGE_READWRITE); + m_pMemory = (LPBYTE)VirtualAlloc(NULL, kMemBankSize, MEM_COMMIT, PAGE_READWRITE); SetMemMainLanguageCard(m_pMemory); } @@ -238,8 +238,8 @@ bool LanguageCardSlot0::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, //------------------------------------- Saturn128K::Saturn128K(UINT banks) + : LanguageCardSlot0(CT_Saturn128K) { - m_type = CT_Saturn128K; m_uSaturnTotalBanks = (banks == 0) ? kMaxSaturnBanks : banks; m_uSaturnActiveBank = 0; diff --git a/source/LanguageCard.h b/source/LanguageCard.h index 7767c877..6f236cb9 100644 --- a/source/LanguageCard.h +++ b/source/LanguageCard.h @@ -1,15 +1,20 @@ #pragma once +#include "Card.h" + // // Language Card (base unit) for Apple //e and above // -class LanguageCardUnit +class LanguageCardUnit : public Card { public: - LanguageCardUnit(void); + LanguageCardUnit(SS_CARDTYPE type = CT_LanguageCardIIe); virtual ~LanguageCardUnit(void); + virtual void Init(void) {}; + virtual void Reset(const bool powerCycle) {}; + virtual void InitializeIO(void); virtual void SetMemorySize(UINT banks) {} // No-op for //e and slot-0 16K LC virtual UINT GetActiveBank(void) { return 0; } // Always 0 as only 1x 16K bank @@ -18,7 +23,7 @@ public: BOOL GetLastRamWrite(void) { return m_uLastRamWrite; } void SetLastRamWrite(BOOL count) { m_uLastRamWrite = count; } - SS_CARDTYPE GetMemoryType(void) { return m_type; } + SS_CARDTYPE GetMemoryType(void) { return QueryType(); } bool IsOpcodeRMWabs(WORD addr); static BYTE __stdcall IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles); @@ -26,9 +31,6 @@ public: static const UINT kMemModeInitialState; static const UINT kSlot0 = 0; -protected: - SS_CARDTYPE m_type; - private: UINT m_uLastRamWrite; }; @@ -40,7 +42,7 @@ private: class LanguageCardSlot0 : public LanguageCardUnit { public: - LanguageCardSlot0(void); + LanguageCardSlot0(SS_CARDTYPE = CT_LanguageCard); virtual ~LanguageCardSlot0(void); virtual void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); diff --git a/source/Memory.cpp b/source/Memory.cpp index fa295225..664fb789 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "Applewin.h" +#include "CardManager.h" #include "CPU.h" #include "Disk.h" #include "Frame.h" @@ -291,8 +292,8 @@ void SetExpansionMemType(const SS_CARDTYPE type) newSlotAuxCard = type; } - g_Slot[0] = newSlot0Card; - g_SlotAux = newSlotAuxCard; + g_CardMgr.Insert(SLOT0, newSlot0Card); + g_CardMgr.InsertAux(newSlotAuxCard); } void CreateLanguageCard(void) @@ -302,9 +303,9 @@ void CreateLanguageCard(void) if (IsApple2PlusOrClone(GetApple2Type())) { - if (g_Slot[0] == CT_Saturn128K) + if (g_CardMgr.QuerySlot(SLOT0) == CT_Saturn128K) g_pLanguageCard = new Saturn128K(g_uSaturnBanksFromCmdLine); - else if (g_Slot[0] == CT_LanguageCard) + else if (g_CardMgr.QuerySlot(SLOT0) == CT_LanguageCard) g_pLanguageCard = new LanguageCardSlot0; else g_pLanguageCard = NULL; @@ -318,9 +319,9 @@ void CreateLanguageCard(void) SS_CARDTYPE GetCurrentExpansionMemType(void) { if (IsApple2PlusOrClone(GetApple2Type())) - return g_Slot[0]; + return g_CardMgr.QuerySlot(SLOT0); else - return g_SlotAux; + return g_CardMgr.QueryAux(); } // @@ -1048,7 +1049,7 @@ static void ResetPaging(BOOL initialize) { SetLastRamWrite(0); - if (IsApple2PlusOrClone(GetApple2Type()) && g_Slot[0] == CT_Empty) + if (IsApple2PlusOrClone(GetApple2Type()) && g_CardMgr.QuerySlot(SLOT0) == CT_Empty) SetMemMode(0); else SetMemMode(LanguageCardUnit::kMemModeInitialState); @@ -1467,7 +1468,7 @@ void MemInitialize() SetExpansionMemTypeDefault(); #ifdef RAMWORKS - if (g_SlotAux == CT_RamWorksIII) + if (g_CardMgr.QueryAux() == CT_RamWorksIII) { // allocate memory for RAMWorks III - up to 8MB g_uActiveBank = 0; @@ -1572,7 +1573,7 @@ void MemInitializeCustomF8ROM(void) const UINT F8RomSize = 0x800; const UINT F8RomOffset = Apple2RomSize-F8RomSize; - if (IsApple2Original(GetApple2Type()) && g_Slot[0] == CT_LanguageCard) + if (IsApple2Original(GetApple2Type()) && g_CardMgr.QuerySlot(SLOT0) == CT_LanguageCard) { try { @@ -1654,13 +1655,13 @@ void MemInitializeIO(void) else RegisterIoHandler(LanguageCardUnit::kSlot0, IO_Null, IO_Null, NULL, NULL, NULL, NULL); - if (g_Slot[1] == CT_GenericPrinter) - PrintLoadRom(pCxRomPeripheral, 1); // $C100 : Parallel printer f/w + if (g_CardMgr.QuerySlot(SLOT1) == CT_GenericPrinter) + PrintLoadRom(pCxRomPeripheral, SLOT1); // $C100 : Parallel printer f/w - if (g_Slot[2] == CT_SSC) - sg_SSC.CommInitialize(pCxRomPeripheral, 2); // $C200 : SSC + if (g_CardMgr.QuerySlot(SLOT2) == CT_SSC) + dynamic_cast(g_CardMgr.GetObj(SLOT2))->CommInitialize(pCxRomPeripheral, SLOT2); // $C200 : SSC - if (g_Slot[3] == CT_Uthernet) + if (g_CardMgr.QuerySlot(SLOT3) == CT_Uthernet) { // Slot 3 contains the Uthernet card (which can coexist with an 80-col+Ram card in AUX slot) // . Uthernet card has no ROM and only IO mapped at $C0Bx @@ -1669,39 +1670,41 @@ void MemInitializeIO(void) // Apple//e: Auxilary slot contains Extended 80 Column card or RamWorksIII card - if (g_Slot[4] == CT_MouseInterface) + if (g_CardMgr.QuerySlot(SLOT4) == CT_MouseInterface) { - sg_Mouse.Initialize(pCxRomPeripheral, 4); // $C400 : Mouse f/w + dynamic_cast(g_CardMgr.GetObj(SLOT4))->Initialize(pCxRomPeripheral, SLOT4); // $C400 : Mouse f/w } - else if (g_Slot[4] == CT_MockingboardC || g_Slot[4] == CT_Phasor) + else if (g_CardMgr.QuerySlot(SLOT4) == CT_MockingboardC || g_CardMgr.QuerySlot(SLOT4) == CT_Phasor) { - const UINT uSlot4 = 4; - const UINT uSlot5 = 5; - MB_InitializeIO(pCxRomPeripheral, uSlot4, uSlot5); + MB_InitializeIO(pCxRomPeripheral, SLOT4, SLOT5); } - else if (g_Slot[4] == CT_Z80) + else if (g_CardMgr.QuerySlot(SLOT4) == CT_Z80) { - ConfigureSoftcard(pCxRomPeripheral, 4); // $C400 : Z80 card + ConfigureSoftcard(pCxRomPeripheral, SLOT4); // $C400 : Z80 card } -// else if (g_Slot[4] == CT_GenericClock) +// else if (g_CardMgr.QuerySlot(SLOT4) == CT_GenericClock) // { -// LoadRom_Clock_Generic(pCxRomPeripheral, 4); +// LoadRom_Clock_Generic(pCxRomPeripheral, SLOT4); // } - if (g_Slot[5] == CT_Z80) + if (g_CardMgr.QuerySlot(SLOT5) == CT_Z80) { - ConfigureSoftcard(pCxRomPeripheral, 5); // $C500 : Z80 card + ConfigureSoftcard(pCxRomPeripheral, SLOT5); // $C500 : Z80 card } - else if (g_Slot[5] == CT_SAM) + else if (g_CardMgr.QuerySlot(SLOT5) == CT_SAM) { - ConfigureSAM(pCxRomPeripheral, 5); // $C500 : Z80 card + ConfigureSAM(pCxRomPeripheral, SLOT5); // $C500 : Z80 card + } + else if (g_CardMgr.QuerySlot(SLOT5) == CT_Disk2) + { + dynamic_cast(g_CardMgr.GetObj(SLOT5))->Initialize(pCxRomPeripheral, SLOT5); // $C500 : Disk][ card } - if (g_Slot[6] == CT_Disk2) - sg_Disk2Card.Initialize(pCxRomPeripheral, 6); // $C600 : Disk][ card + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + dynamic_cast(g_CardMgr.GetObj(SLOT6))->Initialize(pCxRomPeripheral, SLOT6); // $C600 : Disk][ card - if (g_Slot[7] == CT_GenericHDD) - HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w + if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD) + HD_Load_Rom(pCxRomPeripheral, SLOT7); // $C700 : HDD f/w // @@ -2353,8 +2356,8 @@ static void MemLoadSnapshotAuxCommon(YamlLoadHelper& yamlLoadHelper, const std:: yamlLoadHelper.PopMap(); } - g_Slot[0] = CT_Empty; - g_SlotAux = type; + g_CardMgr.Remove(SLOT0); + g_CardMgr.InsertAux(type); memaux = RWpages[g_uActiveBank]; // NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2() diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index 3f830ea5..3429ff72 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -80,6 +80,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "SaveState_Structs_v1.h" #include "Applewin.h" +#include "CardManager.h" #include "CPU.h" #include "Log.h" #include "Memory.h" @@ -1709,21 +1710,21 @@ void MB_InitializeIO(LPBYTE pCxRomPeripheral, UINT uSlot4, UINT uSlot5) // Phasor : Slot 4 // : Slot 4 & 5 - if (g_Slot[4] != CT_MockingboardC && g_Slot[4] != CT_Phasor) + if (g_CardMgr.QuerySlot(SLOT4) != CT_MockingboardC && g_CardMgr.QuerySlot(SLOT4) != CT_Phasor) { MB_SetSoundcardType(CT_Empty); return; } - if (g_Slot[4] == CT_MockingboardC) + if (g_CardMgr.QuerySlot(SLOT4) == CT_MockingboardC) RegisterIoHandler(uSlot4, IO_Null, IO_Null, MB_Read, MB_Write, NULL, NULL); else // Phasor RegisterIoHandler(uSlot4, PhasorIO, PhasorIO, MB_Read, MB_Write, NULL, NULL); - if (g_Slot[5] == CT_MockingboardC) + if (g_CardMgr.QuerySlot(SLOT5) == CT_MockingboardC) RegisterIoHandler(uSlot5, IO_Null, IO_Null, MB_Read, MB_Write, NULL, NULL); - MB_SetSoundcardType(g_Slot[4]); + MB_SetSoundcardType(g_CardMgr.QuerySlot(SLOT4)); if (g_bDisableDirectSound || g_bDisableDirectSoundMockingboard) return; diff --git a/source/Mockingboard.h b/source/Mockingboard.h index 89526938..740e3efa 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -1,5 +1,7 @@ #pragma once +#include "Card.h" + void MB_Initialize(); void MB_Reinitialize(); void MB_Destroy(); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index b4a8e77f..41782b6f 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -129,13 +129,16 @@ void M6821_Listener_A( void* objTo, BYTE byData ) //=========================================================================== -CMouseInterface::CMouseInterface() : +CMouseInterface::CMouseInterface(UINT slot) : + Card(CT_MouseInterface), + m_uSlot(slot), m_pSlotRom(NULL) { m_6821.SetListenerB( this, M6821_Listener_B ); m_6821.SetListenerA( this, M6821_Listener_A ); - Uninitialize(); +// Uninitialize(); + InitializeROM(); Reset(); } @@ -146,8 +149,12 @@ CMouseInterface::~CMouseInterface() //=========================================================================== -void CMouseInterface::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot) +void CMouseInterface::InitializeROM(void) { + _ASSERT(m_pSlotRom == NULL); + if (m_pSlotRom) + return; + const UINT FW_SIZE = 2*1024; HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_MOUSEINTERFACE_FW), "FIRMWARE"); @@ -166,28 +173,24 @@ void CMouseInterface::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot) if(pData == NULL) return; - m_uSlot = uSlot; + m_pSlotRom = new BYTE [FW_SIZE]; + memcpy(m_pSlotRom, pData, FW_SIZE); +} - if (m_pSlotRom == NULL) - { - m_pSlotRom = new BYTE [FW_SIZE]; - - if (m_pSlotRom) - memcpy(m_pSlotRom, pData, FW_SIZE); - } - - // - - m_bActive = true; - SetEnabled(true); +void CMouseInterface::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot) +{ +// m_bActive = true; + m_bEnabled = true; SetSlotRom(); // Pre: m_bActive == true RegisterIoHandler(uSlot, &CMouseInterface::IORead, &CMouseInterface::IOWrite, NULL, NULL, this, NULL); } +#if 0 void CMouseInterface::Uninitialize() { - m_bActive = false; +// m_bActive = false; } +#endif void CMouseInterface::Reset() { @@ -221,8 +224,8 @@ void CMouseInterface::Reset() void CMouseInterface::SetSlotRom() { - if (!m_bActive) - return; +// if (!m_bActive) +// return; LPBYTE pCxRomPeripheral = MemGetCxRomPeripheral(); if (pCxRomPeripheral == NULL) @@ -473,7 +476,7 @@ void CMouseInterface::OnMouseEvent(bool bEventVBL) void CMouseInterface::SetVBlank(bool bVBL) { - _ASSERT(m_bActive); // Only called from CheckInterruptSources(), which is guarded by an: if (sg_Mouse.IsActive()) +// _ASSERT(m_bActive); // Only called from CheckInterruptSources() if ( m_bVBL != bVBL ) { @@ -656,8 +659,8 @@ void CMouseInterface::SaveSnapshotMC6821(YamlSaveHelper& yamlSaveHelper, std::st void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) { - if (!m_bActive) - return; +// if (!m_bActive) +// return; YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_uSlot, 1); diff --git a/source/MouseInterface.h b/source/MouseInterface.h index 6bd08a41..ee16975e 100644 --- a/source/MouseInterface.h +++ b/source/MouseInterface.h @@ -1,25 +1,27 @@ #include "6821.h" #include "Common.h" +#include "Card.h" -extern class CMouseInterface sg_Mouse; - -class CMouseInterface +class CMouseInterface : public Card { public: - CMouseInterface(); + CMouseInterface(UINT slot); virtual ~CMouseInterface(); + virtual void Init(void) {}; + virtual void Reset(const bool powerCycle) {}; + void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot); - void Uninitialize(); +// void Uninitialize(); void Reset(); static BYTE __stdcall IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles); static BYTE __stdcall IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles); void SetPositionRel(long dx, long dy, int* pOutOfBoundsX, int* pOutOfBoundsY); void SetButton(eBUTTON Button, eBUTTONSTATE State); - bool IsActive() { return m_bActive; } +// bool IsActive() { return m_bActive; } bool IsEnabled() { return m_bEnabled; } // NB. m_bEnabled == true implies that m_bActive == true - bool IsActiveAndEnabled() { return IsActive() && IsEnabled(); } // todo: just use IsEnabled() + bool IsActiveAndEnabled() { return /*IsActive() &&*/ IsEnabled(); } // todo: just use IsEnabled() void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; } void SetVBlank(bool bVBL); void GetXY(int& iX, int& iMinX, int& iMaxX, int& iY, int& iMinY, int& iMaxY) @@ -37,11 +39,12 @@ public: m_iY = iY; } - std::string GetSnapshotCardName(void); + static std::string GetSnapshotCardName(void); void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); protected: + void InitializeROM(void); void SetSlotRom(); void On6821_A(BYTE byData); void On6821_B(BYTE byData); @@ -95,7 +98,7 @@ protected: // todo: remove m_bActive: // - instantiate CMouseInterface object when active (and delete when inactive) - bool m_bActive; // Mouse h/w is active within the Apple][ VM +// bool m_bActive; // Mouse h/w is active within the Apple][ VM bool m_bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w (m_bEnabled == true implies that m_bActive == true) LPBYTE m_pSlotRom; UINT m_uSlot; diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 17ea43db..6cf627b2 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "YamlHelper.h" #include "Applewin.h" +#include "CardManager.h" #include "CPU.h" #include "Disk.h" #include "Frame.h" @@ -263,15 +264,17 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT unitVersion) bRes = Printer_LoadSnapshot(yamlLoadHelper, slot, cardVersion); type = CT_GenericPrinter; } - else if (card == sg_SSC.GetSnapshotCardName()) + else if (card == CSuperSerialCard::GetSnapshotCardName()) { - bRes = sg_SSC.LoadSnapshot(yamlLoadHelper, slot, cardVersion); type = CT_SSC; + g_CardMgr.Insert(slot, type); + bRes = dynamic_cast(g_CardMgr.GetObj(slot))->LoadSnapshot(yamlLoadHelper, slot, cardVersion); } - else if (card == sg_Mouse.GetSnapshotCardName()) + else if (card == CMouseInterface::GetSnapshotCardName()) { - bRes = sg_Mouse.LoadSnapshot(yamlLoadHelper, slot, cardVersion); type = CT_MouseInterface; + g_CardMgr.Insert(slot, type); + bRes = dynamic_cast(g_CardMgr.GetObj(slot))->LoadSnapshot(yamlLoadHelper, slot, cardVersion); } else if (card == Z80_GetSnapshotCardName()) { @@ -288,10 +291,11 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT unitVersion) bRes = Phasor_LoadSnapshot(yamlLoadHelper, slot, cardVersion); type = CT_Phasor; } - else if (card == sg_Disk2Card.GetSnapshotCardName()) + else if (card == Disk2InterfaceCard::GetSnapshotCardName()) { - bRes = sg_Disk2Card.LoadSnapshot(yamlLoadHelper, slot, cardVersion); type = CT_Disk2; + g_CardMgr.Insert(slot, type); + bRes = dynamic_cast(g_CardMgr.GetObj(slot))->LoadSnapshot(yamlLoadHelper, slot, cardVersion); } else if (card == HD_GetSnapshotCardName()) { @@ -393,19 +397,35 @@ static void Snapshot_LoadState_v2(void) MemReset(); // Also calls CpuInitialize() PravetsReset(); - sg_Disk2Card.Reset(); + + if (g_CardMgr.IsSSCInstalled()) + { + g_CardMgr.GetSSC()->CommReset(); + } + else + { + _ASSERT(g_CardMgr.QuerySlot(SLOT2) == CT_Empty); + ConfigOld.m_Slot[2] = CT_Empty; + } + + if (g_CardMgr.QuerySlot(SLOT4) == CT_MouseInterface) + g_CardMgr.Remove(SLOT4); // Remove Mouse card from slot-4 + + if (g_CardMgr.QuerySlot(SLOT5) == CT_Disk2) + g_CardMgr.Remove(SLOT5); // Remove Disk2 card from slot-5 + + g_CardMgr.GetDisk2CardMgr().Reset(false); + HD_Reset(); + HD_SetEnabled(false); + KeybReset(); VideoResetState(); SetVideoRefreshRate(VR_60HZ); // Default to 60Hz as older save-states won't contain refresh rate MB_InitializeForLoadingSnapshot(); // GH#609 - sg_SSC.CommReset(); #ifdef USE_SPEECH_API g_Speech.Reset(); #endif - sg_Mouse.Uninitialize(); - sg_Mouse.Reset(); - HD_SetEnabled(false); std::string scalar; while(yamlHelper.GetScalar(scalar)) @@ -431,6 +451,8 @@ static void Snapshot_LoadState_v2(void) MemInitializeCardExpansionRomFromSnapshot(); MemUpdatePaging(TRUE); + + SetMouseCardInstalled( g_CardMgr.IsMouseCardInstalled() ); } catch(std::string szMessage) { @@ -498,39 +520,44 @@ void Snapshot_SaveState(void) yamlSaveHelper.UnitHdr(GetSnapshotUnitSlotsName(), UNIT_SLOTS_VER); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - if (g_Slot[0] != CT_Empty && IsApple2PlusOrClone(GetApple2Type())) + if (g_CardMgr.QuerySlot(SLOT0) != CT_Empty && IsApple2PlusOrClone(GetApple2Type())) GetLanguageCard()->SaveSnapshot(yamlSaveHelper); // Language Card or Saturn 128K - if (g_Slot[1] == CT_GenericPrinter) + if (g_CardMgr.QuerySlot(SLOT1) == CT_GenericPrinter) Printer_SaveSnapshot(yamlSaveHelper); - if (g_Slot[2] == CT_SSC) - sg_SSC.SaveSnapshot(yamlSaveHelper); + if (g_CardMgr.QuerySlot(SLOT2) == CT_SSC) + dynamic_cast(g_CardMgr.GetObj(SLOT2))->SaveSnapshot(yamlSaveHelper); -// if (g_Slot[3] == CT_Uthernet) +// if (g_CardMgr.QuerySlot(SLOT3) == CT_Uthernet) // sg_Uthernet.SaveSnapshot(yamlSaveHelper); - sg_Mouse.SaveSnapshot(yamlSaveHelper); + if (g_CardMgr.QuerySlot(SLOT4) == CT_MouseInterface) + dynamic_cast(g_CardMgr.GetObj(SLOT4))->SaveSnapshot(yamlSaveHelper); - if (g_Slot[4] == CT_Z80) - Z80_SaveSnapshot(yamlSaveHelper, 4); + if (g_CardMgr.QuerySlot(SLOT4) == CT_Z80) + Z80_SaveSnapshot(yamlSaveHelper, SLOT4); - if (g_Slot[5] == CT_Z80) - Z80_SaveSnapshot(yamlSaveHelper, 5); + if (g_CardMgr.QuerySlot(SLOT5) == CT_Z80) + Z80_SaveSnapshot(yamlSaveHelper, SLOT5); - if (g_Slot[4] == CT_MockingboardC) - MB_SaveSnapshot(yamlSaveHelper, 4); + if (g_CardMgr.QuerySlot(SLOT4) == CT_MockingboardC) + MB_SaveSnapshot(yamlSaveHelper, SLOT4); - if (g_Slot[5] == CT_MockingboardC) - MB_SaveSnapshot(yamlSaveHelper, 5); + if (g_CardMgr.QuerySlot(SLOT5) == CT_MockingboardC) + MB_SaveSnapshot(yamlSaveHelper, SLOT5); - if (g_Slot[4] == CT_Phasor) - Phasor_SaveSnapshot(yamlSaveHelper, 4); + if (g_CardMgr.QuerySlot(SLOT4) == CT_Phasor) + Phasor_SaveSnapshot(yamlSaveHelper, SLOT4); - if (g_Slot[6] == CT_Disk2) - sg_Disk2Card.SaveSnapshot(yamlSaveHelper); + if (g_CardMgr.QuerySlot(SLOT5) == CT_Disk2) + dynamic_cast(g_CardMgr.GetObj(SLOT5))->SaveSnapshot(yamlSaveHelper); - HD_SaveSnapshot(yamlSaveHelper); + if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2) + dynamic_cast(g_CardMgr.GetObj(SLOT6))->SaveSnapshot(yamlSaveHelper); + + if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD) + HD_SaveSnapshot(yamlSaveHelper); } } catch(std::string szMessage) diff --git a/source/SaveState_Structs_common.h b/source/SaveState_Structs_common.h index e920753f..c28bf3a3 100644 --- a/source/SaveState_Structs_common.h +++ b/source/SaveState_Structs_common.h @@ -53,29 +53,6 @@ struct SS_CARD_HDR DWORD Slot; // [1..7], 0=Language card, 8=Aux }; -enum SS_CARDTYPE -{ - CT_Empty = 0, - CT_Disk2, // Apple Disk][ - CT_SSC, // Apple Super Serial Card - CT_MockingboardC, // Soundcard - CT_GenericPrinter, - CT_GenericHDD, // Hard disk - CT_GenericClock, - CT_MouseInterface, - CT_Z80, - CT_Phasor, // Soundcard - CT_Echo, // Soundcard - CT_SAM, // Soundcard: Software Automated Mouth - CT_80Col, // 80 column card (1K) - CT_Extended80Col, // Extended 80-col card (64K) - CT_RamWorksIII, // RamWorksIII (up to 8MB) - CT_Uthernet, - CT_LanguageCard, // Apple][ or ][+ in slot-0 - CT_LanguageCardIIe, // Apple//e LC instance (not a card) - CT_Saturn128K, // Saturn 128K (but may be populated with less RAM, in multiples of 16K) -}; - ///////////////////////////////////////////////////////////////////////////////// struct SS_CARD_EMPTY diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index 21d7a05c..a47f72f3 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -65,10 +65,12 @@ SSC_DIPSW CSuperSerialCard::m_DIPSWDefault = //=========================================================================== CSuperSerialCard::CSuperSerialCard() : + Card(CT_SSC), + m_uSlot(0), m_aySerialPortChoices(NULL), m_uTCPChoiceItemIdx(0), - m_uSlot(0), - m_bCfgSupportDCD(false) + m_bCfgSupportDCD(false), + m_pExpansionRom(NULL) { m_ayCurrentSerialPortName.clear(); m_dwSerialPortItem = 0; diff --git a/source/SerialComms.h b/source/SerialComms.h index 71d698b0..318182cb 100644 --- a/source/SerialComms.h +++ b/source/SerialComms.h @@ -1,6 +1,6 @@ #pragma once -extern class CSuperSerialCard sg_SSC; +#include "Card.h" enum {COMMEVT_WAIT=0, COMMEVT_ACK, COMMEVT_TERM, COMMEVT_MAX}; enum eFWMODE {FWMODE_CIC=0, FWMODE_SIC_P8, FWMODE_PPC, FWMODE_SIC_P8A}; // NB. CIC = SSC @@ -22,17 +22,20 @@ typedef struct #define TEXT_SERIAL_COM TEXT("COM") #define TEXT_SERIAL_TCP TEXT("TCP") -class CSuperSerialCard +class CSuperSerialCard : public Card { public: CSuperSerialCard(); virtual ~CSuperSerialCard(); + virtual void Init(void) {}; + virtual void Reset(const bool powerCycle) {}; + void CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot); void CommReset(); void CommDestroy(); void CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem); - std::string GetSnapshotCardName(void); + static std::string GetSnapshotCardName(void); void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); diff --git a/source/Video.cpp b/source/Video.cpp index 806d0558..2f18e73c 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -307,7 +307,7 @@ void VideoBenchmark () { while (cycles > 0) { DWORD executedcycles = CpuExecute(103, true); cycles -= executedcycles; - sg_Disk2Card.UpdateDriveState(executedcycles); + g_CardMgr.GetDisk2CardMgr().UpdateDriveState(executedcycles); JoyUpdateButtonLatch(executedcycles); } }