From ff7c9dc185aed1352e570c583c206af900a8e4f8 Mon Sep 17 00:00:00 2001 From: TomCh Date: Mon, 1 Nov 2021 20:12:42 +0000 Subject: [PATCH] Make harddisk a class (#995) . Add user-protection when unchecking HDD controller (as images aren't restored on a 'cancel') . Fix possible crash when removing (via Config->Disk) either Disk2 card(s5) or HDD card(s7), then cancelling during emulation . Fix m_buf[] size --- source/CardManager.cpp | 3 +- source/CardManager.h | 4 +- source/Configuration/PageDisk.cpp | 55 +- source/Configuration/PropertySheetHelper.cpp | 2 +- source/Disk.cpp | 15 +- source/Disk.h | 2 +- source/Harddisk.cpp | 753 ++++++++----------- source/Harddisk.h | 127 +++- source/Memory.cpp | 12 +- source/Memory.h | 1 + source/SaveState.cpp | 17 +- source/Utilities.cpp | 36 +- source/Utilities.h | 1 - source/Windows/AppleWin.cpp | 7 +- source/Windows/WinFrame.cpp | 14 +- 15 files changed, 523 insertions(+), 526 deletions(-) diff --git a/source/CardManager.cpp b/source/CardManager.cpp index bbc61447..03209bab 100644 --- a/source/CardManager.cpp +++ b/source/CardManager.cpp @@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Disk.h" #include "FourPlay.h" +#include "Harddisk.h" #include "MouseInterface.h" #include "SAM.h" #include "SerialComms.h" @@ -64,7 +65,7 @@ void CardManager::InsertInternal(UINT slot, SS_CARDTYPE type) m_slot[slot] = new DummyCard(type); break; case CT_GenericHDD: - m_slot[slot] = new DummyCard(type); + m_slot[slot] = new HarddiskInterfaceCard(slot); break; case CT_GenericClock: m_slot[slot] = new DummyCard(type); diff --git a/source/CardManager.h b/source/CardManager.h index f1ad191c..1cbd38f3 100644 --- a/source/CardManager.h +++ b/source/CardManager.h @@ -34,13 +34,13 @@ public: Card& GetRef(UINT slot) { SS_CARDTYPE t=QuerySlot(slot); - _ASSERT((t==CT_SSC || t==CT_MouseInterface || t==CT_Disk2 || t == CT_FourPlay || t == CT_SNESMAX || t == CT_SAM) && m_slot[slot]); + _ASSERT((t==CT_GenericHDD || t==CT_SSC || t==CT_MouseInterface || t==CT_Disk2 || t == CT_FourPlay || t == CT_SNESMAX || t == CT_SAM) && m_slot[slot]); return *m_slot[slot]; } Card* GetObj(UINT slot) { SS_CARDTYPE t=QuerySlot(slot); - _ASSERT(t==CT_SSC || t==CT_MouseInterface || t==CT_Disk2 || t == CT_FourPlay || t == CT_SNESMAX || t == CT_SAM); + _ASSERT(t == CT_GenericHDD || t==CT_SSC || t==CT_MouseInterface || t==CT_Disk2 || t == CT_FourPlay || t == CT_SNESMAX || t == CT_SAM); return m_slot[slot]; } diff --git a/source/Configuration/PageDisk.cpp b/source/Configuration/PageDisk.cpp index ddcef077..8589f40e 100644 --- a/source/Configuration/PageDisk.cpp +++ b/source/Configuration/PageDisk.cpp @@ -84,7 +84,7 @@ INT_PTR CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARA if (m_PropertySheetHelper.GetConfigOld().m_Slot[SLOT7] != m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT7]) { if (m_PropertySheetHelper.GetConfigOld().m_Slot[SLOT7] == CT_GenericHDD || m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT7] == CT_GenericHDD) - HD_SetEnabled(m_PropertySheetHelper.GetConfigOld().m_Slot[SLOT7] == CT_GenericHDD); + m_PropertySheetHelper.SetSlot(SLOT7, m_PropertySheetHelper.GetConfigOld().m_Slot[SLOT7]); } DlgCANCEL(hWnd); break; @@ -149,11 +149,20 @@ INT_PTR CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARA case IDC_HDD_ENABLE: { const BOOL checked = IsDlgButtonChecked(hWnd, IDC_HDD_ENABLE) ? TRUE : FALSE; - m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT7] = checked ? CT_GenericHDD : CT_Empty; - // NB. Unusual as it creates slot object when checkbox is toggled (instead of after OK) - // Needed as we need a HarddiskInterfaceCard object so that images can be inserted/ejected [*2] - HD_SetEnabled(m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT7] == CT_GenericHDD); - EnableHDD(hWnd, checked); + // Add some user-protection, as (currently) removing the HDD images can't be undone! + if (checked || !checked && GetFrame().FrameMessageBox("This will unplug the HDD image(s)! Proceed?", "Eject/Unplug Warning", MB_ICONWARNING | MB_YESNO | MB_SETFOREGROUND) != IDNO) + { + m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT7] = checked ? CT_GenericHDD : CT_Empty; + // NB. Unusual as it creates slot object when checkbox is toggled (instead of after OK) + // Needed as we need a HarddiskInterfaceCard object so that images can be inserted/ejected [*2] + m_PropertySheetHelper.SetSlot(SLOT7, m_PropertySheetHelper.GetConfigNew().m_Slot[SLOT7]); + InitComboHDD(hWnd, SLOT7); // disabling will remove the HDD images - so update drop-down to reflect this + EnableHDD(hWnd, checked); + } + else + { + CheckDlgButton(hWnd, IDC_HDD_ENABLE, BST_CHECKED); + } } break; case IDC_HDD_SWAP: @@ -184,7 +193,7 @@ INT_PTR CPageDisk::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARA RegLoadString(TEXT(REG_CONFIG), REGVALUE_CIDERPRESSLOC, 1, PathToCiderPress, MAX_PATH, TEXT("")); SendDlgItemMessage(hWnd, IDC_CIDERPRESS_FILENAME ,WM_SETTEXT, 0, (LPARAM)PathToCiderPress); - CheckDlgButton(hWnd, IDC_HDD_ENABLE, HD_CardIsEnabled() ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hWnd, IDC_HDD_ENABLE, (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) ? BST_CHECKED : BST_UNCHECKED); EnableHDD(hWnd, IsDlgButtonChecked(hWnd, IDC_HDD_ENABLE)); @@ -226,15 +235,19 @@ 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); - if (!HD_GetFullName(HARDDISK_1).empty()) + if (GetCardMgr().QuerySlot(SLOT7) != CT_GenericHDD) + return; + HarddiskInterfaceCard& card = dynamic_cast(GetCardMgr().GetRef(SLOT7)); + + if (!card.GetFullName(HARDDISK_1).empty()) { - SendDlgItemMessage(hWnd, IDC_COMBO_HDD1, CB_INSERTSTRING, 0, (LPARAM)HD_GetFullName(HARDDISK_1).c_str()); + SendDlgItemMessage(hWnd, IDC_COMBO_HDD1, CB_INSERTSTRING, 0, (LPARAM)card.GetFullName(HARDDISK_1).c_str()); SendDlgItemMessage(hWnd, IDC_COMBO_HDD1, CB_SETCURSEL, 0, 0); } - if (!HD_GetFullName(HARDDISK_2).empty()) + if (!card.GetFullName(HARDDISK_2).empty()) { - SendDlgItemMessage(hWnd, IDC_COMBO_HDD2, CB_INSERTSTRING, 0, (LPARAM)HD_GetFullName(HARDDISK_2).c_str()); + SendDlgItemMessage(hWnd, IDC_COMBO_HDD2, CB_INSERTSTRING, 0, (LPARAM)card.GetFullName(HARDDISK_2).c_str()); SendDlgItemMessage(hWnd, IDC_COMBO_HDD2, CB_SETCURSEL, 0, 0); } } @@ -315,6 +328,11 @@ void CPageDisk::HandleHDDCombo(HWND hWnd, UINT driveSelected, UINT comboSelected if (!IsDlgButtonChecked(hWnd, IDC_HDD_ENABLE)) return; + _ASSERT(GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD); + if (GetCardMgr().QuerySlot(SLOT7) != CT_GenericHDD) + return; + HarddiskInterfaceCard& card = dynamic_cast(GetCardMgr().GetRef(SLOT7)); + // Search from "select hard drive" DWORD dwOpenDialogIndex = (DWORD)SendDlgItemMessage(hWnd, comboSelected, CB_FINDSTRINGEXACT, -1, (LPARAM)&m_defaultHDDOptions[0]); DWORD dwComboSelection = (DWORD)SendDlgItemMessage(hWnd, comboSelected, CB_GETCURSEL, 0, 0); @@ -324,7 +342,7 @@ void CPageDisk::HandleHDDCombo(HWND hWnd, UINT driveSelected, UINT comboSelected if (dwComboSelection == dwOpenDialogIndex) { EnableHDD(hWnd, FALSE); // Prevent multiple Selection dialogs to be triggered - bool bRes = HD_Select(driveSelected); + bool bRes = card.Select(driveSelected); EnableHDD(hWnd, TRUE); if (!bRes) @@ -341,13 +359,13 @@ void CPageDisk::HandleHDDCombo(HWND hWnd, UINT driveSelected, UINT comboSelected SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0); } - SendDlgItemMessage(hWnd, comboSelected, CB_INSERTSTRING, 0, (LPARAM)HD_GetFullName(driveSelected).c_str()); + SendDlgItemMessage(hWnd, comboSelected, CB_INSERTSTRING, 0, (LPARAM)card.GetFullName(driveSelected).c_str()); SendDlgItemMessage(hWnd, comboSelected, CB_SETCURSEL, 0, 0); // If the HD was in the other combo, remove now DWORD comboOther = (comboSelected == IDC_COMBO_HDD1) ? IDC_COMBO_HDD2 : IDC_COMBO_HDD1; - DWORD duplicated = (DWORD)SendDlgItemMessage(hWnd, comboOther, CB_FINDSTRINGEXACT, -1, (LPARAM)HD_GetFullName(driveSelected).c_str()); + DWORD duplicated = (DWORD)SendDlgItemMessage(hWnd, comboOther, CB_FINDSTRINGEXACT, -1, (LPARAM)card.GetFullName(driveSelected).c_str()); if (duplicated != CB_ERR) { SendDlgItemMessage(hWnd, comboOther, CB_DELETESTRING, duplicated, 0); @@ -361,7 +379,7 @@ void CPageDisk::HandleHDDCombo(HWND hWnd, UINT driveSelected, UINT comboSelected if (RemovalConfirmation(comboSelected)) { // Unplug selected disk - HD_Unplug(driveSelected); + card.Unplug(driveSelected); // Remove drive from list SendDlgItemMessage(hWnd, comboSelected, CB_DELETESTRING, 0, 0); } @@ -447,7 +465,10 @@ void CPageDisk::HandleHDDSwap(HWND hWnd) if (!RemovalConfirmation(IDC_HDD_SWAP)) return; - if (!HD_ImageSwap()) + if (GetCardMgr().QuerySlot(SLOT7) != CT_GenericHDD) + return; + + if (!dynamic_cast(GetCardMgr().GetRef(SLOT7)).ImageSwap()) return; InitComboHDD(hWnd, SLOT7); @@ -482,7 +503,7 @@ UINT CPageDisk::RemovalConfirmation(UINT uCommand) if (bMsgBox) { - int nRes = GetFrame().FrameMessageBox(szText, TEXT("Eject/Unplug Warning"), MB_ICONWARNING | MB_YESNO | MB_SETFOREGROUND); + int nRes = GetFrame().FrameMessageBox(szText, "Eject/Unplug Warning", MB_ICONWARNING | MB_YESNO | MB_SETFOREGROUND); if (nRes == IDNO) uCommand = 0; } diff --git a/source/Configuration/PropertySheetHelper.cpp b/source/Configuration/PropertySheetHelper.cpp index ec73b969..217d79d3 100644 --- a/source/Configuration/PropertySheetHelper.cpp +++ b/source/Configuration/PropertySheetHelper.cpp @@ -393,7 +393,7 @@ void CPropertySheetHelper::RestoreCurrentConfig(void) SetSlot(SLOT3, m_ConfigOld.m_Slot[SLOT3]); SetSlot(SLOT4, m_ConfigOld.m_Slot[SLOT4]); SetSlot(SLOT5, m_ConfigOld.m_Slot[SLOT5]); - HD_SetEnabled(m_ConfigOld.m_Slot[SLOT7] == CT_GenericHDD); + SetSlot(SLOT7, m_ConfigOld.m_Slot[SLOT7]); GetPropertySheet().SetTheFreezesF8Rom(m_ConfigOld.m_bEnableTheFreezesF8Rom); } diff --git a/source/Disk.cpp b/source/Disk.cpp index b0848700..c0db54c1 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -72,6 +72,10 @@ Disk2InterfaceCard::Disk2InterfaceCard(UINT slot) : ResetLogicStateSequencer(); + // if created by user in Config->Disk, then MemInitializeIO() won't be called + if (GetCxRomPeripheral()) + Initialize(GetCxRomPeripheral()); // During regular start-up, Initialize() will be called later by MemInitializeIO() + // Debug: #if LOG_DISK_NIBBLES_USE_RUNTIME_VAR m_bLogDisk_NibblesRW = false; @@ -86,6 +90,9 @@ Disk2InterfaceCard::~Disk2InterfaceCard(void) { EjectDiskInternal(DRIVE_1); EjectDiskInternal(DRIVE_2); + + // if destroyed by user in Config->Disk, then ensure that old object's reference is removed + UnregisterIoHandler(m_slot); } bool Disk2InterfaceCard::GetEnhanceDisk(void) { return m_enhanceDisk; } @@ -1791,8 +1798,7 @@ void Disk2InterfaceCard::InitFirmware(LPBYTE pCxRomPeripheral) memcpy(pCxRomPeripheral + m_slot*APPLE_SLOT_SIZE, m_16SectorFirmware, DISK2_FW_SIZE); } -// TODO: LoadRom_Disk_Floppy() -void Disk2InterfaceCard::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot) +void Disk2InterfaceCard::Initialize(LPBYTE pCxRomPeripheral) { bool res = GetFirmware(IDR_DISK2_13SECTOR_FW, m_13SectorFirmware); _ASSERT(res); @@ -1807,10 +1813,7 @@ void Disk2InterfaceCard::Initialize(LPBYTE pCxRomPeripheral, UINT uSlot) // . Patching the firmware breaks the ADC checksum used by "The CIA Files" (Tricky Dick) // . In this case we can patch to compensate for an ADC or EOR checksum but not both (nickw) - _ASSERT(m_slot == uSlot); - RegisterIoHandler(uSlot, &Disk2InterfaceCard::IORead, &Disk2InterfaceCard::IOWrite, NULL, NULL, this, NULL); - - m_slot = uSlot; + RegisterIoHandler(m_slot, &Disk2InterfaceCard::IORead, &Disk2InterfaceCard::IOWrite, NULL, NULL, this, NULL); InitFirmware(pCxRomPeripheral); } diff --git a/source/Disk.h b/source/Disk.h index 651f39c6..29280b60 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -130,7 +130,7 @@ public: virtual void Init(void) {}; virtual void Reset(const bool powerCycle); - void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot); + void Initialize(LPBYTE pCxRomPeripheral); void Destroy(void); // no, doesn't "destroy" the disk image. DiskIIManagerShutdown() void Boot(void); diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index dcecd10e..3152e1dc 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -34,7 +34,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "CardManager.h" #include "CPU.h" #include "DiskImage.h" // ImageError_e, Disk_Status_e -#include "DiskImageHelper.h" #include "Memory.h" #include "Registry.h" #include "SaveState.h" @@ -115,101 +114,74 @@ Overview sound card in slot 7 is a generally bad idea) will cause problems. */ -struct HDD + + +HarddiskInterfaceCard::HarddiskInterfaceCard(UINT slot) : + Card(CT_GenericHDD), + m_slot(slot) { - HDD() - { - clear(); - } + m_unitNum = HARDDISK_1 << 7; // b7=unit - void clear() - { - // This is not a POD (there is a std::string) - // memset(0) does not work - imagename.clear(); - fullname.clear(); - strFilenameInZip.clear(); - imagehandle = NULL; - bWriteProtected = false; - hd_error = 0; - hd_memblock = 0; - hd_diskblock = 0; - hd_buf_ptr = 0; - hd_imageloaded = false; - memset(hd_buf, 0, sizeof(hd_buf)); -#if HD_LED - hd_status_next = DISK_STATUS_OFF; - hd_status_prev = DISK_STATUS_OFF; -#endif - } + // The HDD interface has a single Command register for both drives: + // . ProDOS will write to Command before switching drives + m_command = 0; - // From FloppyDisk - std::string imagename; // (ie. no extension) - std::string fullname; // or - std::string strFilenameInZip; // "" or [not used] - ImageInfo* imagehandle; // Init'd by HD_Insert() -> ImageOpen() - bool bWriteProtected; // Needed for ImageOpen() [otherwise not used] - // - BYTE hd_error; // NB. Firmware requires that b0=0 (OK) or b0=1 (Error) - WORD hd_memblock; - UINT hd_diskblock; - WORD hd_buf_ptr; - bool hd_imageloaded; - BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1? Probably for erroreous reads beyond the block size (ie. reads from I/O addr 0xC0F8) + m_saveDiskImage = true; // Save the DiskImage name to Registry -#if HD_LED - Disk_Status_e hd_status_next; - Disk_Status_e hd_status_prev; -#endif -}; + // if created by user in Config->Disk, then MemInitializeIO() won't be called + if (GetCxRomPeripheral()) + Initialize(GetCxRomPeripheral()); // During regular start-up, Initialize() will be called later by MemInitializeIO() +} -static bool g_bHD_RomLoaded = false; -static bool g_bHD_Enabled = false; +HarddiskInterfaceCard::~HarddiskInterfaceCard(void) +{ + CleanupDriveInternal(HARDDISK_1); + CleanupDriveInternal(HARDDISK_2); -static BYTE g_nHD_UnitNum = HARDDISK_1<<7; // b7=unit + // if destroyed by user in Config->Disk, then ensure that old object's reference is removed + UnregisterIoHandler(m_slot); +} -// The HDD interface has a single Command register for both drives: -// . ProDOS will write to Command before switching drives -static BYTE g_nHD_Command; - -static HDD g_HardDisk[NUM_HARDDISKS]; - -static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry -static UINT g_uSlot = SLOT7; +void HarddiskInterfaceCard::Reset(const bool powerCycle) +{ + m_hardDiskDrive[HARDDISK_1].m_error = 0; + m_hardDiskDrive[HARDDISK_2].m_error = 0; +} //=========================================================================== -static void HD_SaveLastDiskImage(const int iDrive); - -static void HD_CleanupDrive(const int iDrive) +void HarddiskInterfaceCard::CleanupDriveInternal(const int iDrive) { - if (g_HardDisk[iDrive].imagehandle) + if (m_hardDiskDrive[iDrive].m_imagehandle) { - ImageClose(g_HardDisk[iDrive].imagehandle); - g_HardDisk[iDrive].imagehandle = NULL; + ImageClose(m_hardDiskDrive[iDrive].m_imagehandle); + m_hardDiskDrive[iDrive].m_imagehandle = NULL; } - g_HardDisk[iDrive].hd_imageloaded = false; + m_hardDiskDrive[iDrive].m_imageloaded = false; - g_HardDisk[iDrive].imagename.clear(); - g_HardDisk[iDrive].fullname.clear(); - g_HardDisk[iDrive].strFilenameInZip.clear(); - - HD_SaveLastDiskImage(iDrive); + m_hardDiskDrive[iDrive].m_imagename.clear(); + m_hardDiskDrive[iDrive].m_fullname.clear(); + m_hardDiskDrive[iDrive].m_strFilenameInZip.clear(); } -//----------------------------------------------------------------------------- +void HarddiskInterfaceCard::CleanupDrive(const int iDrive) +{ + CleanupDriveInternal(iDrive); -static void NotifyInvalidImage(TCHAR* pszImageFilename) + SaveLastDiskImage(iDrive); +} + +//=========================================================================== + +void HarddiskInterfaceCard::NotifyInvalidImage(TCHAR* pszImageFilename) { // TC: TO DO } //=========================================================================== -BOOL HD_Insert(const int iDrive, const std::string& pathname); - -void HD_LoadLastDiskImage(const int drive) +void HarddiskInterfaceCard::LoadLastDiskImage(const int drive) { _ASSERT(drive == HARDDISK_1 || drive == HARDDISK_2); @@ -219,32 +191,32 @@ void HD_LoadLastDiskImage(const int drive) char pathname[MAX_PATH]; - std::string& regSection = RegGetConfigSlotSection(g_uSlot); + std::string& regSection = RegGetConfigSlotSection(m_slot); if (RegLoadString(regSection.c_str(), regKey.c_str(), TRUE, pathname, MAX_PATH, TEXT(""))) { - g_bSaveDiskImage = false; - HD_Insert(drive, pathname); - g_bSaveDiskImage = true; + m_saveDiskImage = false; + Insert(drive, pathname); + m_saveDiskImage = true; } } //=========================================================================== -static void HD_SaveLastDiskImage(const int drive) +void HarddiskInterfaceCard::SaveLastDiskImage(const int drive) { _ASSERT(drive == HARDDISK_1 || drive == HARDDISK_2); - if (!g_bSaveDiskImage) + if (!m_saveDiskImage) return; - std::string& regSection = RegGetConfigSlotSection(g_uSlot); + std::string& regSection = RegGetConfigSlotSection(m_slot); RegSaveValue(regSection.c_str(), REGVALUE_CARD_TYPE, TRUE, CT_GenericHDD); const std::string regKey = (drive == HARDDISK_1) ? REGVALUE_LAST_HARDDISK_1 : REGVALUE_LAST_HARDDISK_2; - const std::string& pathName = HD_GetFullPathName(drive); + const std::string& pathName = HarddiskGetFullPathName(drive); RegSaveString(regSection.c_str(), regKey.c_str(), TRUE, pathName); @@ -252,7 +224,7 @@ static void HD_SaveLastDiskImage(const int drive) // For now, only update 'HDV Starting Directory' for slot7 & drive1 // . otherwise you'll get inconsistent results if you set drive1, then drive2 (and the images were in different folders) - if (g_uSlot != SLOT7 || drive != HARDDISK_1) + if (m_slot != SLOT7 || drive != HARDDISK_1) return; TCHAR szPathName[MAX_PATH]; @@ -267,83 +239,33 @@ static void HD_SaveLastDiskImage(const int drive) //=========================================================================== -// (Nearly) everything below is global - -static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles); - -static const DWORD HDDRVR_SIZE = APPLE_SLOT_SIZE; - -bool HD_CardIsEnabled(void) +const std::string& HarddiskInterfaceCard::GetFullName(const int iDrive) { - return g_bHD_RomLoaded && g_bHD_Enabled; + return m_hardDiskDrive[iDrive].m_fullname; } -// Called by: -// . LoadConfiguration() - Done at each restart -// . RestoreCurrentConfig() - Done when Config dialog is cancelled -// . Snapshot_LoadState_v2() - Done to default to disabled state -void HD_SetEnabled(const bool bEnabled, bool updateRegistry/*=true*/) +const std::string& HarddiskInterfaceCard::HarddiskGetFullPathName(const int iDrive) { - if(g_bHD_Enabled == bEnabled) - return; - - g_bHD_Enabled = bEnabled; - - if (bEnabled) - GetCardMgr().Insert(SLOT7, CT_GenericHDD, updateRegistry); - else - GetCardMgr().Remove(SLOT7); - -#if 0 - // FIXME: For LoadConfiguration(), g_uSlot=7 (see definition at start of file) - // . g_uSlot is only really setup by HD_Load_Rom(), later on - RegisterIoHandler(g_uSlot, HD_IO_EMUL, HD_IO_EMUL, NULL, NULL, NULL, NULL); - - LPBYTE pCxRomPeripheral = MemGetCxRomPeripheral(); - if(pCxRomPeripheral == NULL) // This will be NULL when called after loading value from Registry - return; - - // - - if(g_bHD_Enabled) - HD_Load_Rom(pCxRomPeripheral, g_uSlot); - else - memset(pCxRomPeripheral + g_uSlot*256, 0, HDDRVR_SIZE); -#endif + return ImageGetPathname(m_hardDiskDrive[iDrive].m_imagehandle); } -//------------------------------------- - -const std::string & HD_GetFullName(const int iDrive) +const std::string& HarddiskInterfaceCard::DiskGetBaseName(const int iDrive) { - return g_HardDisk[iDrive].fullname; + return m_hardDiskDrive[iDrive].m_imagename; } -const std::string & HD_GetFullPathName(const int iDrive) -{ - return ImageGetPathname(g_HardDisk[iDrive].imagehandle); -} - -static const std::string & HD_DiskGetBaseName(const int iDrive) -{ - return g_HardDisk[iDrive].imagename; -} - -void HD_GetFilenameAndPathForSaveState(std::string& filename, std::string& path) +void HarddiskInterfaceCard::GetFilenameAndPathForSaveState(std::string& filename, std::string& path) { filename = ""; path = ""; - if (!g_bHD_Enabled) - return; - for (UINT i=HARDDISK_1; i<=HARDDISK_2; i++) { - if (!g_HardDisk[i].hd_imageloaded) + if (!m_hardDiskDrive[i].m_imageloaded) continue; - filename = HD_DiskGetBaseName(i); - std::string pathname = HD_GetFullPathName(i); + filename = DiskGetBaseName(i); + std::string pathname = HarddiskGetFullPathName(i); int idx = pathname.find_last_of(PATH_SEPARATOR); if (idx >= 0 && idx+1 < (int)pathname.length()) // path exists? @@ -357,55 +279,48 @@ void HD_GetFilenameAndPathForSaveState(std::string& filename, std::string& path) } } -//------------------------------------- +//=========================================================================== -void HD_Reset(void) +void HarddiskInterfaceCard::Initialize(const LPBYTE pCxRomPeripheral) { - g_HardDisk[HARDDISK_1].hd_error = 0; - g_HardDisk[HARDDISK_2].hd_error = 0; -} + const DWORD HARDDISK_FW_SIZE = APPLE_SLOT_SIZE; -//------------------------------------- - -void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot) -{ - if(!g_bHD_Enabled) + BYTE* pData = GetFrame().GetResource(IDR_HDDRVR_FW, "FIRMWARE", HARDDISK_FW_SIZE); + if (pData == NULL) return; - BYTE* pData = GetFrame().GetResource(IDR_HDDRVR_FW, "FIRMWARE", HDDRVR_SIZE); - if(pData == NULL) - return; + memcpy(pCxRomPeripheral + m_slot * APPLE_SLOT_SIZE, pData, HARDDISK_FW_SIZE); - g_uSlot = uSlot; - memcpy(pCxRomPeripheral + uSlot*256, pData, HDDRVR_SIZE); - g_bHD_RomLoaded = true; - - RegisterIoHandler(g_uSlot, HD_IO_EMUL, HD_IO_EMUL, NULL, NULL, NULL, NULL); + RegisterIoHandler(m_slot, IORead, IOWrite, NULL, NULL, this, NULL); } -void HD_Destroy(void) +//=========================================================================== + +void HarddiskInterfaceCard::Destroy(void) { - g_bSaveDiskImage = false; - HD_CleanupDrive(HARDDISK_1); + m_saveDiskImage = false; + CleanupDrive(HARDDISK_1); - g_bSaveDiskImage = false; - HD_CleanupDrive(HARDDISK_2); + m_saveDiskImage = false; + CleanupDrive(HARDDISK_2); - g_bSaveDiskImage = true; + m_saveDiskImage = true; } +//=========================================================================== + // Pre: pathname likely to include path (but can also just be filename) -BOOL HD_Insert(const int iDrive, const std::string& pathname) +BOOL HarddiskInterfaceCard::Insert(const int iDrive, const std::string& pathname) { if (pathname.empty()) return FALSE; - if (g_HardDisk[iDrive].hd_imageloaded) - HD_Unplug(iDrive); + if (m_hardDiskDrive[iDrive].m_imageloaded) + Unplug(iDrive); // Check if image is being used by the other HDD, and unplug it in order to be swapped { - const std::string & pszOtherPathname = HD_GetFullPathName(!iDrive); + const std::string & pszOtherPathname = HarddiskGetFullPathName(!iDrive); char szCurrentPathname[MAX_PATH]; DWORD uNameLen = GetFullPathName(pathname.c_str(), MAX_PATH, szCurrentPathname, NULL); @@ -414,7 +329,7 @@ BOOL HD_Insert(const int iDrive, const std::string& pathname) if (!strcmp(pszOtherPathname.c_str(), szCurrentPathname)) { - HD_Unplug(!iDrive); + Unplug(!iDrive); GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS); } } @@ -423,31 +338,31 @@ BOOL HD_Insert(const int iDrive, const std::string& pathname) const bool bExpectFloppy = false; const bool bIsHarddisk = true; ImageError_e Error = ImageOpen(pathname, - &g_HardDisk[iDrive].imagehandle, - &g_HardDisk[iDrive].bWriteProtected, + &m_hardDiskDrive[iDrive].m_imagehandle, + &m_hardDiskDrive[iDrive].m_bWriteProtected, bCreateIfNecessary, - g_HardDisk[iDrive].strFilenameInZip, // TODO: Use this + m_hardDiskDrive[iDrive].m_strFilenameInZip, // TODO: Use this bExpectFloppy); - g_HardDisk[iDrive].hd_imageloaded = (Error == eIMAGE_ERROR_NONE); + m_hardDiskDrive[iDrive].m_imageloaded = (Error == eIMAGE_ERROR_NONE); -#if HD_LED - g_HardDisk[iDrive].hd_status_next = DISK_STATUS_OFF; - g_HardDisk[iDrive].hd_status_prev = DISK_STATUS_OFF; -#endif + m_hardDiskDrive[iDrive].m_status_next = DISK_STATUS_OFF; + m_hardDiskDrive[iDrive].m_status_prev = DISK_STATUS_OFF; if (Error == eIMAGE_ERROR_NONE) { - GetImageTitle(pathname.c_str(), g_HardDisk[iDrive].imagename, g_HardDisk[iDrive].fullname); + GetImageTitle(pathname.c_str(), m_hardDiskDrive[iDrive].m_imagename, m_hardDiskDrive[iDrive].m_fullname); Snapshot_UpdatePath(); } - HD_SaveLastDiskImage(iDrive); + SaveLastDiskImage(iDrive); - return g_HardDisk[iDrive].hd_imageloaded; + return m_hardDiskDrive[iDrive].m_imageloaded; } -static bool HD_SelectImage(const int drive, LPCSTR pszFilename) +//----------------------------------------------------------------------------- + +bool HarddiskInterfaceCard::SelectImage(const int drive, LPCSTR pszFilename) { TCHAR directory[MAX_PATH]; TCHAR filename[MAX_PATH]; @@ -478,7 +393,7 @@ static bool HD_SelectImage(const int drive, LPCSTR pszFilename) if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension]) StringCbCat(filename, MAX_PATH, TEXT(".hdv")); - if (HD_Insert(drive, filename)) + if (Insert(drive, filename)) { bRes = true; } @@ -491,252 +406,241 @@ static bool HD_SelectImage(const int drive, LPCSTR pszFilename) return bRes; } -bool HD_Select(const int iDrive) +bool HarddiskInterfaceCard::Select(const int iDrive) { - return HD_SelectImage(iDrive, TEXT("")); + return SelectImage(iDrive, TEXT("")); } -void HD_Unplug(const int iDrive) +//=========================================================================== + +void HarddiskInterfaceCard::Unplug(const int iDrive) { - if (g_HardDisk[iDrive].hd_imageloaded) + if (m_hardDiskDrive[iDrive].m_imageloaded) { - HD_CleanupDrive(iDrive); + CleanupDrive(iDrive); Snapshot_UpdatePath(); } } -bool HD_IsDriveUnplugged(const int iDrive) +bool HarddiskInterfaceCard::IsDriveUnplugged(const int iDrive) { - return g_HardDisk[iDrive].hd_imageloaded == false; + return m_hardDiskDrive[iDrive].m_imageloaded == false; } -//----------------------------------------------------------------------------- +//=========================================================================== #define DEVICE_OK 0x00 #define DEVICE_UNKNOWN_ERROR 0x28 #define DEVICE_IO_ERROR 0x27 -static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles) +BYTE __stdcall HarddiskInterfaceCard::IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles) { + const UINT slot = ((addr & 0xff) >> 4) - 8; + HarddiskInterfaceCard* pCard = (HarddiskInterfaceCard*)MemGetSlotParameters(slot); + HardDiskDrive* pHDD = &(pCard->m_hardDiskDrive[pCard->m_unitNum >> 7]); // bit7 = drive select + BYTE r = DEVICE_OK; - addr &= 0xFF; + pHDD->m_status_next = DISK_STATUS_READ; - if (!HD_CardIsEnabled()) - return r; - - HDD* pHDD = &g_HardDisk[g_nHD_UnitNum >> 7]; // bit7 = drive select - - if (bWrite == 0) // read + switch (addr & 0xF) { -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_READ; -#endif - switch (addr) - { - case 0xF0: - if (pHDD->hd_imageloaded) + case 0x0: + if (pHDD->m_imageloaded) + { + // based on loaded data block request, load block into memory + // returns status + switch (pCard->m_command) { - // based on loaded data block request, load block into memory - // returns status - switch (g_nHD_Command) - { - default: - case 0x00: //status - if (ImageGetImageSize(pHDD->imagehandle) == 0) + default: + case 0x00: //status + if (ImageGetImageSize(pHDD->m_imagehandle) == 0) + { + pHDD->m_error = 1; + r = DEVICE_IO_ERROR; + } + break; + case 0x01: //read + if ((pHDD->m_diskblock * HD_BLOCK_SIZE) < ImageGetImageSize(pHDD->m_imagehandle)) + { + bool bRes = ImageReadBlock(pHDD->m_imagehandle, pHDD->m_diskblock, pHDD->m_buf); + if (bRes) { - pHDD->hd_error = 1; - r = DEVICE_IO_ERROR; - } - break; - case 0x01: //read - if ((pHDD->hd_diskblock * HD_BLOCK_SIZE) < ImageGetImageSize(pHDD->imagehandle)) - { - bool bRes = ImageReadBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf); - if (bRes) - { - pHDD->hd_error = 0; - r = 0; - pHDD->hd_buf_ptr = 0; - } - else - { - pHDD->hd_error = 1; - r = DEVICE_IO_ERROR; - } + pHDD->m_error = 0; + r = 0; + pHDD->m_buf_ptr = 0; } else { - pHDD->hd_error = 1; + pHDD->m_error = 1; r = DEVICE_IO_ERROR; } - break; - case 0x02: //write + } + else + { + pHDD->m_error = 1; + r = DEVICE_IO_ERROR; + } + break; + case 0x02: //write + { + pHDD->m_status_next = DISK_STATUS_WRITE; + bool bRes = true; + const bool bAppendBlocks = (pHDD->m_diskblock * HD_BLOCK_SIZE) >= ImageGetImageSize(pHDD->m_imagehandle); + + if (bAppendBlocks) { -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_WRITE; -#endif - bool bRes = true; - const bool bAppendBlocks = (pHDD->hd_diskblock * HD_BLOCK_SIZE) >= ImageGetImageSize(pHDD->imagehandle); + memset(pHDD->m_buf, 0, HD_BLOCK_SIZE); - if (bAppendBlocks) + // Inefficient (especially for gzip/zip files!) + UINT uBlock = ImageGetImageSize(pHDD->m_imagehandle) / HD_BLOCK_SIZE; + while (uBlock < pHDD->m_diskblock) { - memset(pHDD->hd_buf, 0, HD_BLOCK_SIZE); - - // Inefficient (especially for gzip/zip files!) - UINT uBlock = ImageGetImageSize(pHDD->imagehandle) / HD_BLOCK_SIZE; - while (uBlock < pHDD->hd_diskblock) - { - bRes = ImageWriteBlock(pHDD->imagehandle, uBlock++, pHDD->hd_buf); - _ASSERT(bRes); - if (!bRes) - break; - } - } - - memmove(pHDD->hd_buf, mem+pHDD->hd_memblock, HD_BLOCK_SIZE); - - if (bRes) - bRes = ImageWriteBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf); - - if (bRes) - { - pHDD->hd_error = 0; - r = 0; - } - else - { - pHDD->hd_error = 1; - r = DEVICE_IO_ERROR; + bRes = ImageWriteBlock(pHDD->m_imagehandle, uBlock++, pHDD->m_buf); + _ASSERT(bRes); + if (!bRes) + break; } } - break; - case 0x03: //format -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_WRITE; -#endif - break; - } + + memmove(pHDD->m_buf, mem+pHDD->m_memblock, HD_BLOCK_SIZE); + + if (bRes) + bRes = ImageWriteBlock(pHDD->m_imagehandle, pHDD->m_diskblock, pHDD->m_buf); + + if (bRes) + { + pHDD->m_error = 0; + r = 0; + } + else + { + pHDD->m_error = 1; + r = DEVICE_IO_ERROR; + } + } + break; + case 0x03: //format + pHDD->m_status_next = DISK_STATUS_WRITE; + break; } - else - { -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_OFF; -#endif - pHDD->hd_error = 1; - r = DEVICE_UNKNOWN_ERROR; - } - break; - case 0xF1: // hd_error -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_OFF; // TODO: FIXME: ??? YELLOW ??? WARNING -#endif - if (pHDD->hd_error) - { - _ASSERT(pHDD->hd_error & 1); - pHDD->hd_error |= 1; // Firmware requires that b0=1 for an error } - - r = pHDD->hd_error; - break; - case 0xF2: - r = g_nHD_Command; - break; - case 0xF3: - r = g_nHD_UnitNum; - break; - case 0xF4: - r = (BYTE)(pHDD->hd_memblock & 0x00FF); - break; - case 0xF5: - r = (BYTE)(pHDD->hd_memblock & 0xFF00 >> 8); - break; - case 0xF6: - r = (BYTE)(pHDD->hd_diskblock & 0x00FF); - break; - case 0xF7: - r = (BYTE)(pHDD->hd_diskblock & 0xFF00 >> 8); - break; - case 0xF8: - r = pHDD->hd_buf[pHDD->hd_buf_ptr]; - if (pHDD->hd_buf_ptr < sizeof(pHDD->hd_buf)-1) - pHDD->hd_buf_ptr++; - break; - default: -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_OFF; -#endif - return IO_Null(pc, addr, bWrite, d, nExecutedCycles); - } - } - else // write to registers - { -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_PROT; // TODO: FIXME: If we ever enable write-protect on HD then need to change to something else ... -#endif - switch (addr) + else + { + pHDD->m_status_next = DISK_STATUS_OFF; + pHDD->m_error = 1; + r = DEVICE_UNKNOWN_ERROR; + } + break; + case 0x1: // m_error + pHDD->m_status_next = DISK_STATUS_OFF; // TODO: FIXME: ??? YELLOW ??? WARNING + if (pHDD->m_error) { - case 0xF2: - g_nHD_Command = d; - break; - case 0xF3: - // b7 = drive# - // b6..4 = slot# - // b3..0 = ? - g_nHD_UnitNum = d; - break; - case 0xF4: - pHDD->hd_memblock = (pHDD->hd_memblock & 0xFF00) | d; - break; - case 0xF5: - pHDD->hd_memblock = (pHDD->hd_memblock & 0x00FF) | (d << 8); - break; - case 0xF6: - pHDD->hd_diskblock = (pHDD->hd_diskblock & 0xFF00) | d; - break; - case 0xF7: - pHDD->hd_diskblock = (pHDD->hd_diskblock & 0x00FF) | (d << 8); - break; - default: -#if HD_LED - pHDD->hd_status_next = DISK_STATUS_OFF; -#endif - return IO_Null(pc, addr, bWrite, d, nExecutedCycles); + _ASSERT(pHDD->m_error & 1); + pHDD->m_error |= 1; // Firmware requires that b0=1 for an error } + + r = pHDD->m_error; + break; + case 0x2: + r = pCard->m_command; + break; + case 0x3: + r = pCard->m_unitNum; + break; + case 0x4: + r = (BYTE)(pHDD->m_memblock & 0x00FF); + break; + case 0x5: + r = (BYTE)(pHDD->m_memblock & 0xFF00 >> 8); + break; + case 0x6: + r = (BYTE)(pHDD->m_diskblock & 0x00FF); + break; + case 0x7: + r = (BYTE)(pHDD->m_diskblock & 0xFF00 >> 8); + break; + case 0x8: + r = pHDD->m_buf[pHDD->m_buf_ptr]; + if (pHDD->m_buf_ptr < sizeof(pHDD->m_buf)-1) + pHDD->m_buf_ptr++; + break; + default: + pHDD->m_status_next = DISK_STATUS_OFF; + r = IO_Null(pc, addr, bWrite, d, nExecutedCycles); } -#if HD_LED - // 1.19.0.0 Hard Disk Status/Indicator Light - if( pHDD->hd_status_prev != pHDD->hd_status_next ) // Update LEDs if state changes - { - pHDD->hd_status_prev = pHDD->hd_status_next; - GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS); - } -#endif - + pCard->UpdateLightStatus(pHDD); return r; } -// 1.19.0.0 Hard Disk Status/Indicator Light -void HD_GetLightStatus (Disk_Status_e *pDisk1Status_) +//----------------------------------------------------------------------------- + +BYTE __stdcall HarddiskInterfaceCard::IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles) { -#if HD_LED - if ( HD_CardIsEnabled() ) + const UINT slot = ((addr & 0xff) >> 4) - 8; + HarddiskInterfaceCard* pCard = (HarddiskInterfaceCard*)MemGetSlotParameters(slot); + HardDiskDrive* pHDD = &(pCard->m_hardDiskDrive[pCard->m_unitNum >> 7]); // bit7 = drive select + + BYTE r = DEVICE_OK; + pHDD->m_status_next = DISK_STATUS_PROT; // TODO: FIXME: If we ever enable write-protect on HD then need to change to something else ... + + switch (addr & 0xF) { - HDD* pHDD = &g_HardDisk[g_nHD_UnitNum >> 7]; // bit7 = drive select - *pDisk1Status_ = pHDD->hd_status_prev; - } else -#endif + case 0x2: + pCard->m_command = d; + break; + case 0x3: + // b7 = drive# + // b6..4 = slot# + // b3..0 = ? + pCard->m_unitNum = d; + break; + case 0x4: + pHDD->m_memblock = (pHDD->m_memblock & 0xFF00) | d; + break; + case 0x5: + pHDD->m_memblock = (pHDD->m_memblock & 0x00FF) | (d << 8); + break; + case 0x6: + pHDD->m_diskblock = (pHDD->m_diskblock & 0xFF00) | d; + break; + case 0x7: + pHDD->m_diskblock = (pHDD->m_diskblock & 0x00FF) | (d << 8); + break; + default: + pHDD->m_status_next = DISK_STATUS_OFF; + r = IO_Null(pc, addr, bWrite, d, nExecutedCycles); + } + + pCard->UpdateLightStatus(pHDD); + return r; +} + +//=========================================================================== + +void HarddiskInterfaceCard::UpdateLightStatus(HardDiskDrive* pHDD) +{ + if (pHDD->m_status_prev != pHDD->m_status_next) // Update LEDs if state changes { - *pDisk1Status_ = DISK_STATUS_OFF; + pHDD->m_status_prev = pHDD->m_status_next; + GetFrame().FrameRefreshStatus(DRAW_LEDS | DRAW_DISK_STATUS); } } -bool HD_ImageSwap(void) +void HarddiskInterfaceCard::GetLightStatus(Disk_Status_e *pDisk1Status) { - std::swap(g_HardDisk[HARDDISK_1], g_HardDisk[HARDDISK_2]); + HardDiskDrive* pHDD = &m_hardDiskDrive[m_unitNum >> 7]; // bit7 = drive select + *pDisk1Status = pHDD->m_status_prev; +} - HD_SaveLastDiskImage(HARDDISK_1); - HD_SaveLastDiskImage(HARDDISK_2); +//=========================================================================== + +bool HarddiskInterfaceCard::ImageSwap(void) +{ + std::swap(m_hardDiskDrive[HARDDISK_1], m_hardDiskDrive[HARDDISK_2]); + + SaveLastDiskImage(HARDDISK_1); + SaveLastDiskImage(HARDDISK_2); GetFrame().FrameRefreshStatus(DRAW_LEDS); @@ -765,70 +669,67 @@ static const UINT kUNIT_VERSION = 2; #define SS_YAML_KEY_BUF_PTR "Buffer Offset" #define SS_YAML_KEY_BUF "Buffer" -std::string HD_GetSnapshotCardName(void) +std::string HarddiskInterfaceCard::GetSnapshotCardName(void) { static const std::string name(SS_YAML_VALUE_CARD_HDD); return name; } -static void HD_SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit) +void HarddiskInterfaceCard::SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit) { YamlSaveHelper::Label label(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_HDDUNIT, unit); - yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_HardDisk[unit].fullname); - yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_ERROR, g_HardDisk[unit].hd_error); - yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_MEMBLOCK, g_HardDisk[unit].hd_memblock); - yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_DISKBLOCK, g_HardDisk[unit].hd_diskblock); - yamlSaveHelper.SaveBool(SS_YAML_KEY_IMAGELOADED, g_HardDisk[unit].hd_imageloaded); - yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_NEXT, g_HardDisk[unit].hd_status_next); - yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_PREV, g_HardDisk[unit].hd_status_prev); - yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_BUF_PTR, g_HardDisk[unit].hd_buf_ptr); + yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, m_hardDiskDrive[unit].m_fullname); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_ERROR, m_hardDiskDrive[unit].m_error); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_MEMBLOCK, m_hardDiskDrive[unit].m_memblock); + yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_DISKBLOCK, m_hardDiskDrive[unit].m_diskblock); + yamlSaveHelper.SaveBool(SS_YAML_KEY_IMAGELOADED, m_hardDiskDrive[unit].m_imageloaded); + yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_NEXT, m_hardDiskDrive[unit].m_status_next); + yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_PREV, m_hardDiskDrive[unit].m_status_prev); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_BUF_PTR, m_hardDiskDrive[unit].m_buf_ptr); // New label { YamlSaveHelper::Label buffer(yamlSaveHelper, "%s:\n", SS_YAML_KEY_BUF); - yamlSaveHelper.SaveMemory(g_HardDisk[unit].hd_buf, HD_BLOCK_SIZE); + yamlSaveHelper.SaveMemory(m_hardDiskDrive[unit].m_buf, HD_BLOCK_SIZE); } } -void HD_SaveSnapshot(YamlSaveHelper& yamlSaveHelper) +void HarddiskInterfaceCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper) { - if (!HD_CardIsEnabled()) - return; - - YamlSaveHelper::Slot slot(yamlSaveHelper, HD_GetSnapshotCardName(), g_uSlot, kUNIT_VERSION); + YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_slot, kUNIT_VERSION); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - yamlSaveHelper.Save("%s: %d # b7=unit\n", SS_YAML_KEY_CURRENT_UNIT, g_nHD_UnitNum); - yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_COMMAND, g_nHD_Command); + yamlSaveHelper.Save("%s: %d # b7=unit\n", SS_YAML_KEY_CURRENT_UNIT, m_unitNum); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_COMMAND, m_command); - HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_1); - HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_2); + SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_1); + SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_2); } -static bool HD_LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) +bool HarddiskInterfaceCard::LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) { std::string hddUnitName = std::string(SS_YAML_KEY_HDDUNIT) + (unit == HARDDISK_1 ? std::string("0") : std::string("1")); if (!yamlLoadHelper.GetSubMap(hddUnitName)) throw std::string("Card: Expected key: ") + hddUnitName; - g_HardDisk[unit].fullname.clear(); - g_HardDisk[unit].imagename.clear(); - g_HardDisk[unit].hd_imageloaded = false; // Default to false (until image is successfully loaded below) - g_HardDisk[unit].hd_status_next = DISK_STATUS_OFF; - g_HardDisk[unit].hd_status_prev = DISK_STATUS_OFF; + m_hardDiskDrive[unit].m_fullname.clear(); + m_hardDiskDrive[unit].m_imagename.clear(); + m_hardDiskDrive[unit].m_imageloaded = false; // Default to false (until image is successfully loaded below) + m_hardDiskDrive[unit].m_status_next = DISK_STATUS_OFF; + m_hardDiskDrive[unit].m_status_prev = DISK_STATUS_OFF; std::string filename = yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME); - g_HardDisk[unit].hd_error = yamlLoadHelper.LoadUint(SS_YAML_KEY_ERROR); - g_HardDisk[unit].hd_memblock = yamlLoadHelper.LoadUint(SS_YAML_KEY_MEMBLOCK); - g_HardDisk[unit].hd_diskblock = yamlLoadHelper.LoadUint(SS_YAML_KEY_DISKBLOCK); + m_hardDiskDrive[unit].m_error = yamlLoadHelper.LoadUint(SS_YAML_KEY_ERROR); + m_hardDiskDrive[unit].m_memblock = yamlLoadHelper.LoadUint(SS_YAML_KEY_MEMBLOCK); + m_hardDiskDrive[unit].m_diskblock = yamlLoadHelper.LoadUint(SS_YAML_KEY_DISKBLOCK); yamlLoadHelper.LoadBool(SS_YAML_KEY_IMAGELOADED); // Consume Disk_Status_e diskStatusNext = (Disk_Status_e) yamlLoadHelper.LoadUint(SS_YAML_KEY_STATUS_NEXT); Disk_Status_e diskStatusPrev = (Disk_Status_e) yamlLoadHelper.LoadUint(SS_YAML_KEY_STATUS_PREV); - g_HardDisk[unit].hd_buf_ptr = yamlLoadHelper.LoadUint(SS_YAML_KEY_BUF_PTR); + m_hardDiskDrive[unit].m_buf_ptr = yamlLoadHelper.LoadUint(SS_YAML_KEY_BUF_PTR); if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_BUF)) throw hddUnitName + std::string(": Missing: ") + std::string(SS_YAML_KEY_BUF); - yamlLoadHelper.LoadMemory(g_HardDisk[unit].hd_buf, HD_BLOCK_SIZE); + yamlLoadHelper.LoadMemory(m_hardDiskDrive[unit].m_buf, HD_BLOCK_SIZE); yamlLoadHelper.PopMap(); yamlLoadHelper.PopMap(); @@ -843,7 +744,7 @@ static bool HD_LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) if (dwAttributes == INVALID_FILE_ATTRIBUTES) { // Get user to browse for file - bResSelectImage = HD_SelectImage(unit, filename.c_str()); + bResSelectImage = SelectImage(unit, filename.c_str()); dwAttributes = GetFileAttributes(filename.c_str()); } @@ -851,27 +752,27 @@ static bool HD_LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES); if (!bImageError) { - if (!HD_Insert(unit, filename.c_str())) + if (!Insert(unit, filename.c_str())) bImageError = true; // HD_Insert() sets up: - // . imagename - // . fullname - // . hd_imageloaded + // . m_imagename + // . m_fullname + // . m_imageloaded // . hd_status_next = DISK_STATUS_OFF // . hd_status_prev = DISK_STATUS_OFF - g_HardDisk[unit].hd_status_next = diskStatusNext; - g_HardDisk[unit].hd_status_prev = diskStatusPrev; + m_hardDiskDrive[unit].m_status_next = diskStatusNext; + m_hardDiskDrive[unit].m_status_prev = diskStatusPrev; } } return bResSelectImage; } -bool HD_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, const std::string & strSaveStatePath) +bool HarddiskInterfaceCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, const std::string& strSaveStatePath) { - if (slot != 7) // fixme + if (slot != SLOT7) // fixme throw std::string("Card: wrong slot"); if (version < 1 || version > kUNIT_VERSION) @@ -880,24 +781,22 @@ bool HD_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, co if (version == 1 && (regs.pc >> 8) == (0xC0|slot)) throw std::string("HDD card: 6502 is running old HDD firmware"); - g_nHD_UnitNum = yamlLoadHelper.LoadUint(SS_YAML_KEY_CURRENT_UNIT); // b7=unit - g_nHD_Command = yamlLoadHelper.LoadUint(SS_YAML_KEY_COMMAND); + m_unitNum = yamlLoadHelper.LoadUint(SS_YAML_KEY_CURRENT_UNIT); // b7=unit + m_command = yamlLoadHelper.LoadUint(SS_YAML_KEY_COMMAND); // Unplug all HDDs first in case HDD-2 is to be plugged in as HDD-1 for (UINT i=0; i (ie. no extension) + std::string m_fullname; // or + std::string m_strFilenameInZip; // "" or [not used] + ImageInfo* m_imagehandle; // Init'd by HD_Insert() -> ImageOpen() + bool m_bWriteProtected; // Needed for ImageOpen() [otherwise not used] + // + BYTE m_error; // NB. Firmware requires that b0=0 (OK) or b0=1 (Error) + WORD m_memblock; + UINT m_diskblock; + WORD m_buf_ptr; + bool m_imageloaded; + BYTE m_buf[HD_BLOCK_SIZE]; - std::string HD_GetSnapshotCardName(void); - void HD_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); - bool HD_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, const std::string & strSaveStatePath); + Disk_Status_e m_status_next; + Disk_Status_e m_status_prev; +}; + +class HarddiskInterfaceCard : public Card +{ +public: + HarddiskInterfaceCard(UINT slot); + virtual ~HarddiskInterfaceCard(void); + + virtual void Init(void) {} + virtual void Reset(const bool powerCycle); + + void Initialize(const LPBYTE pCxRomPeripheral); + void Destroy(void); + const std::string& GetFullName(const int iDrive); + const std::string& HarddiskGetFullPathName(const int iDrive); + void GetFilenameAndPathForSaveState(std::string& filename, std::string& path); + bool Select(const int iDrive); + BOOL Insert(const int iDrive, const std::string& pathname); + void Unplug(const int iDrive); + bool IsDriveUnplugged(const int iDrive); + void LoadLastDiskImage(const int iDrive); + + void GetLightStatus(Disk_Status_e* pDisk1Status); + bool ImageSwap(void); + + static std::string GetSnapshotCardName(void); + void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); + bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, const std::string& strSaveStatePath); + + static BYTE __stdcall IORead(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles); + static BYTE __stdcall IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nExecutedCycles); + +private: + void CleanupDriveInternal(const int iDrive); + void CleanupDrive(const int iDrive); + void NotifyInvalidImage(TCHAR* pszImageFilename); + void SaveLastDiskImage(const int drive); + const std::string& DiskGetBaseName(const int iDrive); + bool SelectImage(const int drive, LPCSTR pszFilename); + void UpdateLightStatus(HardDiskDrive* pHDD); + + void SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit); + bool LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit); + + // + + BYTE m_unitNum; // b7=unit + BYTE m_command; + + bool m_saveDiskImage; // Save the DiskImage name to Registry + UINT m_slot; + + HardDiskDrive m_hardDiskDrive[NUM_HARDDISKS]; +}; diff --git a/source/Memory.cpp b/source/Memory.cpp index b3c71683..35818a1b 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -1012,6 +1012,12 @@ void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, io ExpansionRom[uSlot] = pExpansionRom; } +void UnregisterIoHandler(UINT uSlot) +{ + RegisterIoHandler(uSlot, NULL, NULL, NULL, NULL, NULL, NULL); + g_SlotInfo[uSlot].bHasCard = false; +} + // From UTAIIe:5-28: Since INTCXROM==1 then state of SLOTC3ROM is not important static void IoHandlerCardsOut(void) { @@ -1784,14 +1790,14 @@ void MemInitializeIO(void) } else if (GetCardMgr().QuerySlot(SLOT5) == CT_Disk2) { - dynamic_cast(GetCardMgr().GetRef(SLOT5)).Initialize(pCxRomPeripheral, SLOT5); // $C500 : Disk][ card + dynamic_cast(GetCardMgr().GetRef(SLOT5)).Initialize(pCxRomPeripheral); // $C500 : Disk][ card } if (GetCardMgr().QuerySlot(SLOT6) == CT_Disk2) - dynamic_cast(GetCardMgr().GetRef(SLOT6)).Initialize(pCxRomPeripheral, SLOT6); // $C600 : Disk][ card + dynamic_cast(GetCardMgr().GetRef(SLOT6)).Initialize(pCxRomPeripheral); // $C600 : Disk][ card if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) - HD_Load_Rom(pCxRomPeripheral, SLOT7); // $C700 : HDD f/w + dynamic_cast(GetCardMgr().GetRef(SLOT7)).Initialize(pCxRomPeripheral); } // Called by: diff --git a/source/Memory.h b/source/Memory.h index fe2d9c60..c20a8cf1 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -60,6 +60,7 @@ const UINT kMaxExMemoryBanks = 127; // 127 * aux mem(64K) + main mem(64K) = 8MB #endif void RegisterIoHandler(UINT uSlot, iofunction IOReadC0, iofunction IOWriteC0, iofunction IOReadCx, iofunction IOWriteCx, LPVOID lpSlotParameter, BYTE* pExpansionRom); +void UnregisterIoHandler(UINT uSlot); void MemDestroy (); bool MemCheckSLOTC3ROM(); diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 7d838ef8..776dd81e 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -147,7 +147,10 @@ void Snapshot_GetDefaultFilenameAndPath(std::string& defaultFilename, std::strin { // Attempt to get a default filename/path based on harddisk plugged-in or floppy disk inserted // . Priority given to harddisk over floppy images - HD_GetFilenameAndPathForSaveState(defaultFilename, defaultPath); + + if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) + dynamic_cast(GetCardMgr().GetRef(SLOT7)).GetFilenameAndPathForSaveState(defaultFilename, defaultPath); + if (defaultFilename.empty()) GetCardMgr().GetDisk2CardMgr().GetFilenameAndPathForSaveState(defaultFilename, defaultPath); } @@ -370,11 +373,11 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT unitVersion) GetCardMgr().Insert(slot, type); bRes = dynamic_cast(GetCardMgr().GetRef(slot)).LoadSnapshot(yamlLoadHelper, slot, cardVersion); } - else if (card == HD_GetSnapshotCardName()) + else if (card == HarddiskInterfaceCard::GetSnapshotCardName()) { type = CT_GenericHDD; GetCardMgr().Insert(slot, type); - bRes = HD_LoadSnapshot(yamlLoadHelper, slot, cardVersion, g_strSaveStatePath); + bRes = dynamic_cast(GetCardMgr().GetRef(slot)).LoadSnapshot(yamlLoadHelper, slot, cardVersion, g_strSaveStatePath); } else if (card == tfe_GetSnapshotCardName()) { @@ -496,9 +499,6 @@ static void Snapshot_LoadState_v2(void) MemReset(); // Also calls CpuInitialize() GetPravets().Reset(); - HD_Reset(); - HD_SetEnabled(false); // Set disabled & also removes card from slot 7 - KeybReset(); GetVideo().VideoResetState(); GetVideo().SetVideoRefreshRate(VR_60HZ); // Default to 60Hz as older save-states won't contain refresh rate @@ -574,9 +574,6 @@ void Snapshot_LoadState() //----------------------------------------------------------------------------- -// todo: -// . Uthernet card - void Snapshot_SaveState(void) { try @@ -646,7 +643,7 @@ void Snapshot_SaveState(void) dynamic_cast(GetCardMgr().GetRef(SLOT6)).SaveSnapshot(yamlSaveHelper); if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) - HD_SaveSnapshot(yamlSaveHelper); + dynamic_cast(GetCardMgr().GetRef(SLOT7)).SaveSnapshot(yamlSaveHelper); for (UINT slot = SLOT3; slot <= SLOT5; slot++) { diff --git a/source/Utilities.cpp b/source/Utilities.cpp index 6ad14c83..f75715b2 100644 --- a/source/Utilities.cpp +++ b/source/Utilities.cpp @@ -267,11 +267,6 @@ void LoadConfiguration(void) tfe_init(true); } } - else if (slot == SLOT7) - { - if ((SS_CARDTYPE)dwTmp == CT_GenericHDD) // TODO: move this to when HarddiskInterfaceCard object is instantiated - HD_SetEnabled(true, false); - } } else // legacy (AppleWin 1.30.3 or earlier) { @@ -296,7 +291,7 @@ void LoadConfiguration(void) else if (slot == SLOT5 && REGLOAD(TEXT(REGVALUE_SLOT5), &dwTmp)) GetCardMgr().Insert(SLOT5, (SS_CARDTYPE)dwTmp); else if (slot == SLOT7 && REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp)) - HD_SetEnabled(dwTmp ? true : false); + GetCardMgr().Insert(SLOT7, (SS_CARDTYPE)dwTmp); } } @@ -314,8 +309,11 @@ void LoadConfiguration(void) GetCurrentDirectory(sizeof(szFilename), szFilename); SetCurrentImageDir(szFilename); - HD_LoadLastDiskImage(HARDDISK_1); - HD_LoadLastDiskImage(HARDDISK_2); + if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) + { + dynamic_cast(GetCardMgr().GetRef(SLOT7)).LoadLastDiskImage(HARDDISK_1); + dynamic_cast(GetCardMgr().GetRef(SLOT7)).LoadLastDiskImage(HARDDISK_2); + } // @@ -401,16 +399,20 @@ static bool DoDiskInsert(const UINT slot, const int nDrive, LPCSTR szFileName) static bool DoHardDiskInsert(const int nDrive, LPCSTR szFileName) { + _ASSERT(GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD); + if (GetCardMgr().QuerySlot(SLOT7) != CT_GenericHDD) + return false; + if (szFileName[0] == '\0') { - HD_Unplug(nDrive); + dynamic_cast(GetCardMgr().GetRef(SLOT7)).Unplug(nDrive); return true; } std::string strPathName = GetFullPath(szFileName); if (strPathName.empty()) return false; - BOOL bRes = HD_Insert(nDrive, strPathName); + BOOL bRes = dynamic_cast(GetCardMgr().GetRef(SLOT7)).Insert(nDrive, strPathName); bool res = (bRes == TRUE); if (res) SetCurrentDir(strPathName); @@ -454,7 +456,8 @@ void InsertHardDisks(LPCSTR szImageName_harddisk[NUM_HARDDISKS], bool& bBoot) if (!szImageName_harddisk[HARDDISK_1] && !szImageName_harddisk[HARDDISK_2]) return; - HD_SetEnabled(true); // Enable the Harddisk controller card + if (GetCardMgr().QuerySlot(SLOT7) != CT_GenericHDD) + GetCardMgr().Insert(SLOT7, CT_GenericHDD); // Enable the Harddisk controller card bool bRes = true; @@ -476,11 +479,6 @@ void InsertHardDisks(LPCSTR szImageName_harddisk[NUM_HARDDISKS], bool& bBoot) GetFrame().FrameMessageBox("Failed to insert harddisk(s) - see log file", "Warning", MB_ICONASTERISK | MB_OK); } -void UnplugHardDiskControllerCard(void) -{ - HD_SetEnabled(false); -} - void GetAppleWindowTitle() { switch (g_Apple2Type) @@ -541,7 +539,8 @@ void GetAppleWindowTitle() void ResetMachineState() { GetCardMgr().GetDisk2CardMgr().Reset(true); - HD_Reset(); + if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) + dynamic_cast(GetCardMgr().GetRef(SLOT7)).Reset(true); g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted MemReset(); // calls CpuInitialize(), CNoSlotClock.Reset() @@ -595,7 +594,8 @@ void CtrlReset() GetPravets().Reset(); GetCardMgr().GetDisk2CardMgr().Reset(); - HD_Reset(); + if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) + dynamic_cast(GetCardMgr().GetRef(SLOT7)).Reset(true); KeybReset(); if (GetCardMgr().IsSSCInstalled()) GetCardMgr().GetSSC()->CommReset(); diff --git a/source/Utilities.h b/source/Utilities.h index 43ac6a01..14ce5079 100644 --- a/source/Utilities.h +++ b/source/Utilities.h @@ -7,7 +7,6 @@ void LoadConfiguration(); void InsertFloppyDisks(const UINT slot, LPCSTR szImageName_drive[NUM_DRIVES], bool driveConnected[NUM_DRIVES], bool& bBoot); void InsertHardDisks(LPCSTR szImageName_harddisk[NUM_HARDDISKS], bool& bBoot); -void UnplugHardDiskControllerCard(void); void GetAppleWindowTitle(); void CtrlReset(); diff --git a/source/Windows/AppleWin.cpp b/source/Windows/AppleWin.cpp index cc068cd6..017ed8c8 100644 --- a/source/Windows/AppleWin.cpp +++ b/source/Windows/AppleWin.cpp @@ -782,7 +782,7 @@ static void RepeatInitialization(void) if (g_cmdLine.bSlotEmpty[SLOT7]) { - HD_SetEnabled(false); // Disable HDD controller, and persist this to Registry/conf.ini (consistent with other '-sn empty' cmds) + GetCardMgr().Remove(SLOT7); // Disable HDD controller, and persist this to Registry/conf.ini (consistent with other '-sn empty' cmds) Snapshot_UpdatePath(); // If save-state's filename is a harddisk, and the floppy is in the same path, then the filename won't be updated } } @@ -821,7 +821,8 @@ static void RepeatInitialization(void) // Need to test if it's safe to call ResetMachineState(). In the meantime, just call Disk2Card's Reset(): GetCardMgr().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 + if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) + dynamic_cast(GetCardMgr().GetRef(SLOT7)).Reset(true); // GH#515 LogFileOutput("Main: HDDReset()\n"); if (!g_bSysClkOK) @@ -916,7 +917,7 @@ static void Shutdown(void) CloseHandle(g_hCustomRom); if (g_cmdLine.bSlot7EmptyOnExit) - UnplugHardDiskControllerCard(); + GetCardMgr().Remove(SLOT7); } IPropertySheet& GetPropertySheet(void) diff --git a/source/Windows/WinFrame.cpp b/source/Windows/WinFrame.cpp index 8b3e5b5a..8c3c2a40 100644 --- a/source/Windows/WinFrame.cpp +++ b/source/Windows/WinFrame.cpp @@ -741,11 +741,9 @@ void Win32Frame::DrawStatusArea (HDC passdc, int drawflags) int y = buttony+BUTTONS*BUTTONCY+1; const bool bCaps = KeybGetCapsStatus(); -#if HD_LED - // 1.19.0.0 Hard Disk Status/Indicator Light Disk_Status_e eHardDriveStatus = DISK_STATUS_OFF; - HD_GetLightStatus(&eHardDriveStatus); -#endif + if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) + dynamic_cast(GetCardMgr().GetRef(SLOT7)).GetLightStatus(&eHardDriveStatus); if (g_bIsFullScreen) { @@ -764,11 +762,9 @@ void Win32Frame::DrawStatusArea (HDC passdc, int drawflags) FrameDrawDiskStatus(dc); } -#if HD_LED SetTextAlign(dc, TA_RIGHT | TA_TOP); SetTextColor(dc, g_aDiskFullScreenColorsLED[ eHardDriveStatus ] ); TextOut(dc,x+23,y+2,TEXT("H"),1); -#endif if (!IS_APPLE2) { @@ -849,11 +845,8 @@ void Win32Frame::DrawStatusArea (HDC passdc, int drawflags) case A2TYPE_PRAVETS8A : DrawBitmapRect(dc,x+31,y+17,&rCapsLed,g_hCapsBitmapP8 [bCaps != 0]); break; } -#if HD_LED - // 1.19.0.0 Hard Disk Status/Indicator Light RECT rDiskLed = {0,0,8,8}; DrawBitmapRect(dc,x+12,y+18,&rDiskLed,g_hDiskWindowedLED[eHardDriveStatus]); -#endif } } @@ -968,7 +961,8 @@ LRESULT Win32Frame::WndProc( DebugDestroy(); if (!g_bRestart) { GetCardMgr().GetDisk2CardMgr().Destroy(); - HD_Destroy(); + if (GetCardMgr().QuerySlot(SLOT7) == CT_GenericHDD) + dynamic_cast(GetCardMgr().GetRef(SLOT7)).Destroy(); } PrintDestroy(); if (GetCardMgr().IsSSCInstalled())