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