diff --git a/Src/BeebEm.vcxproj b/Src/BeebEm.vcxproj
index dbe3c6de..9c09afbf 100644
--- a/Src/BeebEm.vcxproj
+++ b/Src/BeebEm.vcxproj
@@ -179,6 +179,7 @@
+
diff --git a/Src/BeebEm.vcxproj.filters b/Src/BeebEm.vcxproj.filters
index 9952b720..16c01f9d 100644
--- a/Src/BeebEm.vcxproj.filters
+++ b/Src/BeebEm.vcxproj.filters
@@ -114,6 +114,9 @@
Source Files
+
+ Source Files
+
Source Files
diff --git a/Src/BeebWin.cpp b/Src/BeebWin.cpp
index de459d89..a511734e 100644
--- a/Src/BeebWin.cpp
+++ b/Src/BeebWin.cpp
@@ -120,11 +120,6 @@ LEDType LEDs;
LEDColour DiscLedColour = LEDColour::Red;
-// FDC Board extension DLL variables
-HMODULE hFDCBoard;
-EDCB ExtBoard={0,0,NULL};
-char FDCDLL[256]={0};
-
const char *WindowTitle = "BeebEm - BBC Model B / Master 128 Emulator";
/****************************************************************************/
@@ -3744,8 +3739,10 @@ void BeebWin::HandleCommand(UINT MenuID)
case ID_8271:
KillDLLs();
NativeFDC = true;
+
CheckMenuItem(ID_8271, true);
CheckMenuItem(ID_FDC_DLL, false);
+
if (MachineType != Model::Master128)
{
char CfgName[20];
diff --git a/Src/BeebWinDx.cpp b/Src/BeebWinDx.cpp
index a76ab1c9..24d606b7 100644
--- a/Src/BeebWinDx.cpp
+++ b/Src/BeebWinDx.cpp
@@ -36,9 +36,6 @@ Boston, MA 02110-1301, USA.
typedef HRESULT (WINAPI* LPDIRECTDRAWCREATE)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter);
-extern HMODULE hFDCBoard;
-extern EDCB ExtBoard;
-
/****************************************************************************/
void BeebWin::InitDX()
{
@@ -855,11 +852,13 @@ void BeebWin::DisplayClientAreaText(HDC hdc)
/****************************************************************************/
void BeebWin::DisplayFDCBoardInfo(HDC hDC, int x, int y)
{
- if (DisplayCycles > 0 && hFDCBoard != NULL)
+ if (DisplayCycles > 0 && HasFDCBoard())
{
+ const char* BoardName = GetFDCBoardName();
+
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, 0x808080);
- TextOut(hDC, x, y, ExtBoard.BoardName, (int)strlen(ExtBoard.BoardName));
+ TextOut(hDC, x, y, BoardName, (int)strlen(BoardName));
}
}
diff --git a/Src/BeebWinIo.cpp b/Src/BeebWinIo.cpp
index dca5f0a0..9fa157c2 100644
--- a/Src/BeebWinIo.cpp
+++ b/Src/BeebWinIo.cpp
@@ -63,17 +63,6 @@ using std::max;
using namespace Gdiplus;
-extern EDCB ExtBoard;
-extern char FDCDLL[256];
-extern HMODULE hFDCBoard;
-
-typedef void (*lGetBoardProperties)(struct DriveControlBlock *);
-typedef unsigned char (*lSetDriveControl)(unsigned char);
-typedef unsigned char (*lGetDriveControl)(unsigned char);
-lGetBoardProperties PGetBoardProperties;
-lSetDriveControl PSetDriveControl;
-lGetDriveControl PGetDriveControl;
-
/****************************************************************************/
void BeebWin::SetImageName(const char *DiscName, int Drive, DiscType Type)
@@ -468,8 +457,9 @@ void BeebWin::SelectFDC()
}
else
{
- strcpy(FDCDLL,FileName);
+ strcpy(FDCDLL, FileName);
}
+
LoadFDC(FDCDLL, true);
}
}
@@ -1103,80 +1093,74 @@ void BeebWin::LoadFDC(char *DLLName, bool save)
char CfgName[20];
sprintf(CfgName, "FDCDLL%d", static_cast(MachineType));
- if (hFDCBoard != nullptr)
- {
- FreeLibrary(hFDCBoard);
- hFDCBoard = nullptr;
- }
+ Ext1770Reset();
NativeFDC = true;
- if (DLLName == NULL) {
+ if (DLLName == nullptr)
+ {
if (!m_Preferences.GetStringValue(CfgName, FDCDLL))
- strcpy(FDCDLL,"None");
+ strcpy(FDCDLL, "None");
DLLName = FDCDLL;
}
- if (strcmp(DLLName, "None")) {
+ if (strcmp(DLLName, "None") != 0)
+ {
char path[_MAX_PATH];
strcpy(path, DLLName);
GetDataPath(m_AppPath, path);
- hFDCBoard=LoadLibrary(path);
- if (hFDCBoard==NULL) {
+ Ext1770Result Result = Ext1770Init(path);
+
+ if (Result == Ext1770Result::Success)
+ {
+ NativeFDC = false; // at last, a working DLL!
+ }
+ else if (Result == Ext1770Result::LoadFailed)
+ {
Report(MessageType::Error, "Unable to load FDD Extension Board DLL\nReverting to native 8271");
strcpy(DLLName, "None");
}
- else {
- PGetBoardProperties=(lGetBoardProperties) GetProcAddress(hFDCBoard,"GetBoardProperties");
- PSetDriveControl=(lSetDriveControl) GetProcAddress(hFDCBoard,"SetDriveControl");
- PGetDriveControl=(lGetDriveControl) GetProcAddress(hFDCBoard,"GetDriveControl");
- if ((PGetBoardProperties==NULL) || (PSetDriveControl==NULL) || (PGetDriveControl==NULL)) {
- Report(MessageType::Error, "Invalid FDD Extension Board DLL\nReverting to native 8271");
- strcpy(DLLName, "None");
- }
- else {
- PGetBoardProperties(&ExtBoard);
- EFDCAddr=ExtBoard.FDCAddress;
- EDCAddr=ExtBoard.DCAddress;
- NativeFDC = false; // at last, a working DLL!
- InvertTR00=ExtBoard.TR00_ActiveHigh;
- }
- }
+ else // if (Result == InvalidDLL)
+ {
+ Report(MessageType::Error, "Invalid FDD Extension Board DLL\nReverting to native 8271");
+ strcpy(DLLName, "None");
+ }
}
if (save)
+ {
m_Preferences.SetStringValue(CfgName, DLLName);
+ }
// Set menu options
CheckMenuItem(ID_8271, NativeFDC);
CheckMenuItem(ID_FDC_DLL, !NativeFDC);
- DisplayCycles=7000000;
+ DisplayCycles = 7000000;
+
if (NativeFDC || MachineType == Model::Master128)
- DisplayCycles=0;
+ DisplayCycles = 0;
}
void BeebWin::KillDLLs()
{
- if (hFDCBoard != nullptr)
- {
- FreeLibrary(hFDCBoard);
- hFDCBoard = nullptr;
- }
+ Ext1770Reset();
}
-void BeebWin::SetDriveControl(unsigned char value) {
- // This takes a value from the mem/io decoder, as written by the cpu, runs it through the
- // DLL's translator, then sends it on to the 1770 FDC in master 128 form.
- WriteFDCControlReg(PSetDriveControl(value));
+void BeebWin::SetDriveControl(unsigned char Value)
+{
+ // This takes a value from the mem/io decoder, as written by the CPU,
+ // runs it through the DLL's translator, then sends it on to the
+ // 1770 FDC in Master 128 form.
+ WriteFDCControlReg(::SetDriveControl(Value));
}
-unsigned char BeebWin::GetDriveControl(void) {
- // Same as above, but in reverse, i.e. reading
- unsigned char temp=ReadFDCControlReg();
- unsigned char temp2=PGetDriveControl(temp);
- return(temp2);
+unsigned char BeebWin::GetDriveControl()
+{
+ // Same as above, but in reverse, i.e., reading.
+ unsigned char temp = ReadFDCControlReg();
+ return ::GetDriveControl(temp);
}
/****************************************************************************/
diff --git a/Src/Disc1770.cpp b/Src/Disc1770.cpp
index f3476c01..60c825b5 100644
--- a/Src/Disc1770.cpp
+++ b/Src/Disc1770.cpp
@@ -31,6 +31,7 @@ Written by Richard Gellman - Feb 2001
#include "Disc1770.h"
#include "6502core.h"
#include "DiscInfo.h"
+#include "Ext1770.h"
#include "FileUtils.h"
#include "Log.h"
#include "Main.h"
@@ -1265,7 +1266,6 @@ bool CreateADFSImage(const char *FileName, int Tracks) {
void Save1770UEF(FILE *SUEF)
{
- extern char FDCDLL[256];
char blank[256];
memset(blank,0,256);
@@ -1341,7 +1341,6 @@ void Save1770UEF(FILE *SUEF)
void Load1770UEF(FILE *SUEF, int Version)
{
- extern char FDCDLL[256];
char FileName[256];
bool Loaded = false;
bool LoadFailed = false;
diff --git a/Src/Ext1770.cpp b/Src/Ext1770.cpp
new file mode 100644
index 00000000..b54b1f37
--- /dev/null
+++ b/Src/Ext1770.cpp
@@ -0,0 +1,125 @@
+/****************************************************************
+BeebEm - BBC Micro and Master 128 Emulator
+Copyright (C) 2001 Richard Gellman
+
+This program 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.
+
+This program 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 this program; if not, write to the Free
+Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.
+****************************************************************/
+
+#include
+
+#include "Ext1770.h"
+#include "BeebMem.h"
+#include "Disc1770.h"
+
+/*--------------------------------------------------------------------------*/
+
+struct DriveControlBlock
+{
+ int FDCAddress; // 1770 FDC chip address
+ int DCAddress; // Drive Control Register Address
+ const char *BoardName; // FDC Board name
+ bool TR00_ActiveHigh; // Set true if the TR00 input is Active High
+};
+
+// FDC Board extension DLL variables
+char FDCDLL[256] = { 0 };
+
+static HMODULE hFDCBoard = nullptr;
+static DriveControlBlock ExtBoard = { 0, 0, nullptr };
+
+typedef void (*GetBoardPropertiesFunc)(struct DriveControlBlock *);
+typedef unsigned char (*SetDriveControlFunc)(unsigned char);
+typedef unsigned char (*GetDriveControlFunc)(unsigned char);
+
+GetBoardPropertiesFunc PGetBoardProperties;
+SetDriveControlFunc PSetDriveControl;
+GetDriveControlFunc PGetDriveControl;
+
+/*--------------------------------------------------------------------------*/
+
+void Ext1770Reset()
+{
+ if (hFDCBoard != nullptr)
+ {
+ FreeLibrary(hFDCBoard);
+ hFDCBoard = nullptr;
+ }
+
+ PGetBoardProperties = nullptr;
+ PSetDriveControl = nullptr;
+ PGetDriveControl = nullptr;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Ext1770Result Ext1770Init(const char *FileName)
+{
+ hFDCBoard = LoadLibrary(FileName);
+
+ if (hFDCBoard == nullptr)
+ {
+ return Ext1770Result::LoadFailed;
+ }
+
+ PGetBoardProperties = (GetBoardPropertiesFunc)GetProcAddress(hFDCBoard, "GetBoardProperties");
+ PSetDriveControl = (SetDriveControlFunc)GetProcAddress(hFDCBoard, "SetDriveControl");
+ PGetDriveControl = (GetDriveControlFunc)GetProcAddress(hFDCBoard, "GetDriveControl");
+
+ if (PGetBoardProperties == nullptr ||
+ PSetDriveControl == nullptr ||
+ PGetDriveControl == nullptr)
+ {
+ Ext1770Reset();
+
+ return Ext1770Result::InvalidDLL;
+ }
+
+ PGetBoardProperties(&ExtBoard);
+
+ EFDCAddr = ExtBoard.FDCAddress;
+ EDCAddr = ExtBoard.DCAddress;
+ InvertTR00 = ExtBoard.TR00_ActiveHigh;
+
+ return Ext1770Result::Success;
+}
+
+/*--------------------------------------------------------------------------*/
+
+bool HasFDCBoard()
+{
+ return hFDCBoard != nullptr;
+}
+
+/*--------------------------------------------------------------------------*/
+
+const char* GetFDCBoardName()
+{
+ return ExtBoard.BoardName;
+}
+
+/*--------------------------------------------------------------------------*/
+
+unsigned char GetDriveControl(unsigned char Value)
+{
+ return PGetDriveControl(Value);
+}
+
+/*--------------------------------------------------------------------------*/
+
+unsigned char SetDriveControl(unsigned char Value)
+{
+ return PSetDriveControl(Value);
+}
diff --git a/Src/Ext1770.h b/Src/Ext1770.h
index 8e26e559..0b0a6b1e 100644
--- a/Src/Ext1770.h
+++ b/Src/Ext1770.h
@@ -12,19 +12,33 @@ 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 this program; if not, write to the Free
+You should have received a copy of the GNU General Public
+License along with this program; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
****************************************************************/
// Opus DDFS Board Drive Controller Chip DLL
// (C) September 2001 - Richard Gellman
-struct DriveControlBlock {
- int FDCAddress; // 1770 FDC chip address
- int DCAddress; // Drive Control Register Address
- char *BoardName; // FDC Board name
- bool TR00_ActiveHigh; // Set true if the TR00 input is Active High
+#ifndef EXT1770_HEADER
+#define EXT1770_HEADER
+
+enum class Ext1770Result
+{
+ Success,
+ LoadFailed,
+ InvalidDLL
};
-#define EDCB struct DriveControlBlock
+void Ext1770Reset();
+Ext1770Result Ext1770Init(const char *FileName);
+bool HasFDCBoard();
+
+unsigned char SetDriveControl(unsigned char Value);
+unsigned char GetDriveControl(unsigned char Value);
+
+const char* GetFDCBoardName();
+
+extern char FDCDLL[256];
+
+#endif