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