Support 2nd Disk][ card and improved card management (#726) (PR #741)

Support 2nd Disk][ in slot-5, via command line:
- -s5 diskii
- -s5d1 \<imagefile\>
- -s5d2 \<imagefile\>

NB. there's currently no Configuration UI support, except the Drive icons' tooltips show what's in slot-5 & slot-6 (for drive-n). So there's no way to eject the disks or insert new disks. The use-case I'm supporting it Wasteland which just has the 4 disks in the 4 drives.

Improved card management:
- Added `class Card` (in Card.h) which all other cards (that exist as classes) derive from (eg. LC,SSC,Mouse,Disk2).
- Added `class CardManager` (in CardManager.cpp\h) which now manages the 8 slots (and aux slot).
- Added `class Disk2CardManager` (in Disk2CardManager.cpp\h) which provides methods for operations that act on all Disk2 instances at the same time.
- Currently limited to just 1x SSC and 1x Mouse card (why would you need more?). This simplifies things, meaning there's no need to have dedicated SSCManager / MouseCardManager objects.
- Currently the 2nd Disk2 card can only be put into slot-5. This limitation is just due to the complexity of the Configuration UI. Having a more general drop-down per slot UI would remove this limitation.
This commit is contained in:
TomCh 2019-12-19 19:42:30 +00:00 committed by GitHub
parent d2010860ef
commit 769d4c6927
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 1169 additions and 418 deletions

View File

@ -609,6 +609,18 @@
RelativePath=".\source\AY8910.h"
>
</File>
<File
RelativePath=".\source\Card.h"
>
</File>
<File
RelativePath=".\source\CardManager.cpp"
>
</File>
<File
RelativePath=".\source\CardManager.h"
>
</File>
<File
RelativePath=".\source\Joystick.cpp"
>
@ -837,6 +849,14 @@
RelativePath=".\source\Disk.h"
>
</File>
<File
RelativePath=".\source\Disk2CardManager.cpp"
>
</File>
<File
RelativePath=".\source\Disk2CardManager.h"
>
</File>
<File
RelativePath=".\source\DiskDefs.h"
>

View File

@ -24,6 +24,8 @@
<ClInclude Include="source\6821.h" />
<ClInclude Include="source\Applewin.h" />
<ClInclude Include="source\AY8910.h" />
<ClInclude Include="source\Card.h" />
<ClInclude Include="source\CardManager.h" />
<ClInclude Include="source\Common.h" />
<ClInclude Include="source\CommonVICE\6510core.h" />
<ClInclude Include="source\CommonVICE\alarm.h" />
@ -62,6 +64,7 @@
<ClInclude Include="source\Debugger\Util_MemoryTextFile.h" />
<ClInclude Include="source\Debugger\Util_Text.h" />
<ClInclude Include="source\Disk.h" />
<ClInclude Include="source\Disk2CardManager.h" />
<ClInclude Include="source\DiskDefs.h" />
<ClInclude Include="source\DiskFormatTrack.h" />
<ClInclude Include="source\DiskImage.h" />
@ -125,6 +128,7 @@
<ClCompile Include="source\6821.cpp" />
<ClCompile Include="source\Applewin.cpp" />
<ClCompile Include="source\AY8910.cpp" />
<ClCompile Include="source\CardManager.cpp" />
<ClCompile Include="source\Configuration\About.cpp" />
<ClCompile Include="source\Configuration\PageAdvanced.cpp" />
<ClCompile Include="source\Configuration\PageConfig.cpp" />
@ -135,6 +139,7 @@
<ClCompile Include="source\Configuration\PropertySheet.cpp" />
<ClCompile Include="source\Configuration\PropertySheetHelper.cpp" />
<ClCompile Include="source\CPU.cpp" />
<ClCompile Include="source\Disk2CardManager.cpp" />
<ClCompile Include="source\RGBMonitor.cpp" />
<ClCompile Include="source\SAM.cpp" />
<ClCompile Include="source\Debugger\Debug.cpp" />
@ -302,7 +307,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{0A960136-A00A-4D4B-805F-664D9950D2CA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>AppleWinExpress2013</RootNamespace>
<RootNamespace>AppleWin</RootNamespace>
<ProjectName>AppleWin</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@ -373,7 +378,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<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;%(AdditionalDependencies)</AdditionalDependencies>
<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)</AdditionalDependencies>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>
</Link>
@ -428,7 +433,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<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;%(AdditionalDependencies)</AdditionalDependencies>
<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)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalManifestDependencies>"type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"</AdditionalManifestDependencies>
<MinimumRequiredVersion>5.01</MinimumRequiredVersion>

View File

@ -193,6 +193,12 @@
<ClCompile Include="source\RGBMonitor.cpp">
<Filter>Source Files\Video</Filter>
</ClCompile>
<ClCompile Include="source\CardManager.cpp">
<Filter>Source Files\Emulator</Filter>
</ClCompile>
<ClCompile Include="source\Disk2CardManager.cpp">
<Filter>Source Files\Disk</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="source\Applewin.h">
@ -471,6 +477,15 @@
<ClInclude Include="source\RGBMonitor.h">
<Filter>Source Files\Video</Filter>
</ClInclude>
<ClInclude Include="source\Card.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
<ClInclude Include="source\CardManager.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
<ClInclude Include="source\Disk2CardManager.h">
<Filter>Source Files\Disk</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="resource\Applewin.bmp">

View File

@ -24,6 +24,8 @@
<ClInclude Include="source\6821.h" />
<ClInclude Include="source\Applewin.h" />
<ClInclude Include="source\AY8910.h" />
<ClInclude Include="source\Card.h" />
<ClInclude Include="source\CardManager.h" />
<ClInclude Include="source\Common.h" />
<ClInclude Include="source\CommonVICE\6510core.h" />
<ClInclude Include="source\CommonVICE\alarm.h" />
@ -62,6 +64,7 @@
<ClInclude Include="source\Debugger\Util_MemoryTextFile.h" />
<ClInclude Include="source\Debugger\Util_Text.h" />
<ClInclude Include="source\Disk.h" />
<ClInclude Include="source\Disk2CardManager.h" />
<ClInclude Include="source\DiskDefs.h" />
<ClInclude Include="source\DiskFormatTrack.h" />
<ClInclude Include="source\DiskImage.h" />
@ -125,6 +128,7 @@
<ClCompile Include="source\6821.cpp" />
<ClCompile Include="source\Applewin.cpp" />
<ClCompile Include="source\AY8910.cpp" />
<ClCompile Include="source\CardManager.cpp" />
<ClCompile Include="source\Configuration\About.cpp" />
<ClCompile Include="source\Configuration\PageAdvanced.cpp" />
<ClCompile Include="source\Configuration\PageConfig.cpp" />
@ -135,6 +139,7 @@
<ClCompile Include="source\Configuration\PropertySheet.cpp" />
<ClCompile Include="source\Configuration\PropertySheetHelper.cpp" />
<ClCompile Include="source\CPU.cpp" />
<ClCompile Include="source\Disk2CardManager.cpp" />
<ClCompile Include="source\RGBMonitor.cpp" />
<ClCompile Include="source\SAM.cpp" />
<ClCompile Include="source\Debugger\Debug.cpp" />
@ -302,7 +307,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{0A960136-A00A-4D4B-805F-664D9950D2CA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>AppleWinExpress2013</RootNamespace>
<RootNamespace>AppleWin</RootNamespace>
<ProjectName>AppleWin</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

View File

@ -193,6 +193,12 @@
<ClCompile Include="source\RGBMonitor.cpp">
<Filter>Source Files\Video</Filter>
</ClCompile>
<ClCompile Include="source\Disk2CardManager.cpp">
<Filter>Source Files\Disk</Filter>
</ClCompile>
<ClCompile Include="source\CardManager.cpp">
<Filter>Source Files\Emulator</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="source\Applewin.h">
@ -471,6 +477,15 @@
<ClInclude Include="source\RGBMonitor.h">
<Filter>Source Files\Video</Filter>
</ClInclude>
<ClInclude Include="source\Disk2CardManager.h">
<Filter>Source Files\Disk</Filter>
</ClInclude>
<ClInclude Include="source\Card.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
<ClInclude Include="source\CardManager.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="resource\Applewin.bmp">

View File

@ -24,6 +24,8 @@
<ClInclude Include="source\6821.h" />
<ClInclude Include="source\Applewin.h" />
<ClInclude Include="source\AY8910.h" />
<ClInclude Include="source\Card.h" />
<ClInclude Include="source\CardManager.h" />
<ClInclude Include="source\Common.h" />
<ClInclude Include="source\CommonVICE\6510core.h" />
<ClInclude Include="source\CommonVICE\alarm.h" />
@ -62,6 +64,7 @@
<ClInclude Include="source\Debugger\Util_MemoryTextFile.h" />
<ClInclude Include="source\Debugger\Util_Text.h" />
<ClInclude Include="source\Disk.h" />
<ClInclude Include="source\Disk2CardManager.h" />
<ClInclude Include="source\DiskDefs.h" />
<ClInclude Include="source\DiskFormatTrack.h" />
<ClInclude Include="source\DiskImage.h" />
@ -125,6 +128,7 @@
<ClCompile Include="source\6821.cpp" />
<ClCompile Include="source\Applewin.cpp" />
<ClCompile Include="source\AY8910.cpp" />
<ClCompile Include="source\CardManager.cpp" />
<ClCompile Include="source\Configuration\About.cpp" />
<ClCompile Include="source\Configuration\PageAdvanced.cpp" />
<ClCompile Include="source\Configuration\PageConfig.cpp" />
@ -135,6 +139,7 @@
<ClCompile Include="source\Configuration\PropertySheet.cpp" />
<ClCompile Include="source\Configuration\PropertySheetHelper.cpp" />
<ClCompile Include="source\CPU.cpp" />
<ClCompile Include="source\Disk2CardManager.cpp" />
<ClCompile Include="source\RGBMonitor.cpp" />
<ClCompile Include="source\SAM.cpp" />
<ClCompile Include="source\Debugger\Debug.cpp" />

View File

@ -193,6 +193,12 @@
<ClCompile Include="source\RGBMonitor.cpp">
<Filter>Source Files\Video</Filter>
</ClCompile>
<ClCompile Include="source\Disk2CardManager.cpp">
<Filter>Source Files\Disk</Filter>
</ClCompile>
<ClCompile Include="source\CardManager.cpp">
<Filter>Source Files\Emulator</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="source\Applewin.h">
@ -471,6 +477,15 @@
<ClInclude Include="source\RGBMonitor.h">
<Filter>Source Files\Video</Filter>
</ClInclude>
<ClInclude Include="source\Disk2CardManager.h">
<Filter>Source Files\Disk</Filter>
</ClInclude>
<ClInclude Include="source\Card.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
<ClInclude Include="source\CardManager.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="resource\Applewin.bmp">

View File

@ -24,6 +24,8 @@
<ClInclude Include="source\6821.h" />
<ClInclude Include="source\Applewin.h" />
<ClInclude Include="source\AY8910.h" />
<ClInclude Include="source\Card.h" />
<ClInclude Include="source\CardManager.h" />
<ClInclude Include="source\Common.h" />
<ClInclude Include="source\CommonVICE\6510core.h" />
<ClInclude Include="source\CommonVICE\alarm.h" />
@ -62,6 +64,7 @@
<ClInclude Include="source\Debugger\Util_MemoryTextFile.h" />
<ClInclude Include="source\Debugger\Util_Text.h" />
<ClInclude Include="source\Disk.h" />
<ClInclude Include="source\Disk2CardManager.h" />
<ClInclude Include="source\DiskDefs.h" />
<ClInclude Include="source\DiskFormatTrack.h" />
<ClInclude Include="source\DiskImage.h" />
@ -125,6 +128,7 @@
<ClCompile Include="source\6821.cpp" />
<ClCompile Include="source\Applewin.cpp" />
<ClCompile Include="source\AY8910.cpp" />
<ClCompile Include="source\CardManager.cpp" />
<ClCompile Include="source\Configuration\About.cpp" />
<ClCompile Include="source\Configuration\PageAdvanced.cpp" />
<ClCompile Include="source\Configuration\PageConfig.cpp" />
@ -135,6 +139,7 @@
<ClCompile Include="source\Configuration\PropertySheet.cpp" />
<ClCompile Include="source\Configuration\PropertySheetHelper.cpp" />
<ClCompile Include="source\CPU.cpp" />
<ClCompile Include="source\Disk2CardManager.cpp" />
<ClCompile Include="source\RGBMonitor.cpp" />
<ClCompile Include="source\SAM.cpp" />
<ClCompile Include="source\Debugger\Debug.cpp" />

View File

@ -193,6 +193,12 @@
<ClCompile Include="source\RGBMonitor.cpp">
<Filter>Source Files\Video</Filter>
</ClCompile>
<ClCompile Include="source\CardManager.cpp">
<Filter>Source Files\Emulator</Filter>
</ClCompile>
<ClCompile Include="source\Disk2CardManager.cpp">
<Filter>Source Files\Disk</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="source\Applewin.h">
@ -471,6 +477,15 @@
<ClInclude Include="source\RGBMonitor.h">
<Filter>Source Files\Video</Filter>
</ClInclude>
<ClInclude Include="source\CardManager.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
<ClInclude Include="source\Disk2CardManager.h">
<Filter>Source Files\Disk</Filter>
</ClInclude>
<ClInclude Include="source\Card.h">
<Filter>Source Files\Emulator</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="resource\Applewin.bmp">

View File

@ -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<Disk2InterfaceCard*> (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] <card>
{
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] <dsk-image>
{
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");

View File

@ -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

View File

@ -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

View File

@ -45,3 +45,4 @@ void SetActiveCpu(eCpuType cpu);
bool Is6502InterruptEnabled(void);
void ResetCyclesExecutedForDebugger(void);
void SetMouseCardInstalled(bool installed);

65
source/Card.h Normal file
View File

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

155
source/CardManager.cpp Normal file
View File

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

56
source/CardManager.h Normal file
View File

@ -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; i<NUM_SLOTS; i++)
Remove(i);
RemoveAux();
}
void Insert(UINT slot, SS_CARDTYPE type);
void Remove(UINT slot);
SS_CARDTYPE QuerySlot(UINT slot) { return m_slot[slot]->QueryType(); }
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;
};

View File

@ -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)

View File

@ -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() );
}
//

View File

@ -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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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)

View File

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

View File

@ -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)

View File

@ -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<Disk2InterfaceCard*>(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);

View File

@ -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<Disk2InterfaceCard*>(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);
}

View File

@ -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)

View File

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

120
source/Disk2CardManager.cpp Normal file
View File

@ -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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(g_CardMgr.GetObj(i))->LoadLastDiskImage(DRIVE_1);
dynamic_cast<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(g_CardMgr.GetObj(i))->Destroy();
}
}
}

16
source/Disk2CardManager.h Normal file
View File

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

View File

@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <sys/stat.h>
#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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(g_CardMgr.GetObj(SLOT5));
if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2)
pDisk2Slot6 = dynamic_cast<Disk2InterfaceCard*>(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 = "<empty>";
if (slot5.empty()) slot5 = "<empty>";
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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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));

View File

@ -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)

View File

@ -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;

View File

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

View File

@ -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<CSuperSerialCard*>(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<CMouseInterface*>(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<Disk2InterfaceCard*>(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<Disk2InterfaceCard*>(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()

View File

@ -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
// <other> : 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;

View File

@ -1,5 +1,7 @@
#pragma once
#include "Card.h"
void MB_Initialize();
void MB_Reinitialize();
void MB_Destroy();

View File

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

View File

@ -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;

View File

@ -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<CSuperSerialCard*>(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<CMouseInterface*>(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<Disk2InterfaceCard*>(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<CSuperSerialCard*>(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<CMouseInterface*>(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<Disk2InterfaceCard*>(g_CardMgr.GetObj(SLOT5))->SaveSnapshot(yamlSaveHelper);
HD_SaveSnapshot(yamlSaveHelper);
if (g_CardMgr.QuerySlot(SLOT6) == CT_Disk2)
dynamic_cast<Disk2InterfaceCard*>(g_CardMgr.GetObj(SLOT6))->SaveSnapshot(yamlSaveHelper);
if (g_CardMgr.QuerySlot(SLOT7) == CT_GenericHDD)
HD_SaveSnapshot(yamlSaveHelper);
}
}
catch(std::string szMessage)

View File

@ -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

View File

@ -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;

View File

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

View File

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