Skip to content

Commit

Permalink
Fixed support for double-sided SSD files
Browse files Browse the repository at this point in the history
These didn't work with the 1770 FDC, and file import
and export also weren't working
  • Loading branch information
chrisn committed Dec 22, 2023
1 parent e7e8774 commit 5b31437
Show file tree
Hide file tree
Showing 15 changed files with 524 additions and 372 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Contributors: Chris Needham, Mauro Varischetti, Bill Carr, Daniel Beardsmore

* Added support for FSD format disk images. This currently only works
with the 8271 and not the 1770 disk controller.
* Fixed support for double-sided SSD disk images (where side 1 tracks
follow side 0, as opposed to DSD images, where tracks from side 0 and 1 are
interleaved). This only works for 80-track double-sided SSDs, not 40-track.
* Added icons for disk and tape image file types. The installer now allows
you to create file associations for these, and saved state files.
* BeebEm saved state files now use the .uefstate file extension, to distinguish
Expand Down
2 changes: 2 additions & 0 deletions Src/BeebEm.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
<ClCompile Include="disc1770.cpp" />
<ClCompile Include="disc8271.cpp" />
<ClCompile Include="DiscEdit.cpp" />
<ClCompile Include="DiscInfo.cpp" />
<ClCompile Include="Econet.cpp" />
<ClCompile Include="ExportFileDialog.cpp" />
<ClCompile Include="FileDialog.cpp" />
Expand Down Expand Up @@ -345,6 +346,7 @@
<ClInclude Include="disc1770.h" />
<ClInclude Include="disc8271.h" />
<ClInclude Include="DiscEdit.h" />
<ClInclude Include="DiscInfo.h" />
<ClInclude Include="DiscType.h" />
<ClInclude Include="Econet.h" />
<ClInclude Include="ExportFileDialog.h" />
Expand Down
6 changes: 6 additions & 0 deletions Src/BeebEm.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@
<ClCompile Include="DiscEdit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DiscInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Econet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down Expand Up @@ -353,6 +356,9 @@
<ClInclude Include="DiscEdit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DiscInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DiscType.h">
<Filter>Header Files</Filter>
</ClInclude>
Expand Down
38 changes: 30 additions & 8 deletions Src/DiscEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ Boston, MA 02110-1301, USA.
#include <string>

#include "DiscEdit.h"
#include "DiscInfo.h"
#include "FileDialog.h"
#include "FileUtils.h"

static int DFS_LENGTH_TO_SECTORS(int Length)
{
Expand Down Expand Up @@ -102,18 +104,28 @@ bool dfs_get_catalogue(const char *szDiscFile,

FILE* fd = fopen(szDiscFile, "rb");

if (fd == NULL)
if (fd == nullptr)
{
success = false;
}
else
{
bool DoubleSidedSSD = IsDoubleSidedSSD(szDiscFile, fd);

int catOffset = 0;

if (numSides == 2 && side == 1)
{
// Tracks are interleaved in a double sided disc image
catOffset = DFS_SECTORS_PER_TRACK * DFS_SECTOR_SIZE;
if (DoubleSidedSSD)
{
// Tracks are not interleaved, so side 2 appears after side 1
catOffset = 80 * DFS_SECTORS_PER_TRACK * DFS_SECTOR_SIZE;
}
else
{
// Tracks are interleaved in a double sided disc image
catOffset = DFS_SECTORS_PER_TRACK * DFS_SECTOR_SIZE;
}
}

if (fseek(fd, catOffset, SEEK_SET) != 0)
Expand Down Expand Up @@ -187,7 +199,7 @@ bool dfs_export_file(const char *szDiscFile,

FILE *discfd = fopen(szDiscFile, "rb");

if (discfd == NULL)
if (discfd == nullptr)
{
sprintf(szErrStr, "Failed to open disc file:\n %s", szDiscFile);
return false;
Expand All @@ -202,6 +214,8 @@ bool dfs_export_file(const char *szDiscFile,
}
else
{
bool DoubleSidedSSD = IsDoubleSidedSSD(szDiscFile, discfd);

// Export the data
int sector = attr->startSector;
int len = attr->length;
Expand All @@ -217,10 +231,18 @@ bool dfs_export_file(const char *szDiscFile,
}
else
{
track = sector / DFS_SECTORS_PER_TRACK;
offset = (track * 2 + side) * DFS_SECTORS_PER_TRACK;
offset += (sector % DFS_SECTORS_PER_TRACK);
offset *= DFS_SECTOR_SIZE;
if (DoubleSidedSSD)
{
offset = 80 * DFS_SECTORS_PER_TRACK * DFS_SECTOR_SIZE;
offset += sector * DFS_SECTOR_SIZE;
}
else
{
track = sector / DFS_SECTORS_PER_TRACK;
offset = (track * 2 + side) * DFS_SECTORS_PER_TRACK;
offset += (sector % DFS_SECTORS_PER_TRACK);
offset *= DFS_SECTOR_SIZE;
}
}

// Read next sector
Expand Down
43 changes: 43 additions & 0 deletions Src/DiscInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/****************************************************************
BeebEm - BBC Micro and Master 128 Emulator
Copyright (C) 2009 Mike Wyatt
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 <stdio.h>

#include "DiscInfo.h"
#include "DiscEdit.h"
#include "FileUtils.h"

DiscInfoType DiscInfo[2];

bool IsDoubleSidedSSD(const char *FileName, FILE *pFile)
{
if (!HasFileExt(FileName, ".ssd"))
{
return false;
}

fseek(pFile, 0, SEEK_END);

long Size = ftell(pFile);

fseek(pFile, 0, SEEK_SET);

return Size > 80 * DFS_SECTORS_PER_TRACK * DFS_SECTOR_SIZE;
}
38 changes: 38 additions & 0 deletions Src/DiscInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/****************************************************************
BeebEm - BBC Micro and Master 128 Emulator
Copyright (C) 2009 Mike Wyatt
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.
****************************************************************/

#ifndef DISCINFO_HEADER
#define DISCINFO_HEADER

#include "DiscType.h"

struct DiscInfoType
{
bool Loaded; // Set to true when a disc image has been loaded
char FileName[256]; // Filename of disc currently in drive 0 and 1
DiscType Type; // Current disc type
bool DoubleSidedSSD; // Non-interleaved double sided disk image
};

extern DiscInfoType DiscInfo[2];

bool IsDoubleSidedSSD(const char *FileName, FILE *pFile);

#endif
9 changes: 9 additions & 0 deletions Src/FileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,12 @@ std::string AppendPath(const std::string& BasePath, const std::string& Path)

return PathName;
}

bool HasFileExt(const char* FileName, const char* Ext)
{
const size_t ExtLen = strlen(Ext);
const size_t FileNameLen = strlen(FileName);

return FileNameLen >= ExtLen &&
_stricmp(FileName + FileNameLen - ExtLen, Ext) == 0;
}
2 changes: 2 additions & 0 deletions Src/FileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ bool FolderExists(const char* PathName);

std::string AppendPath(const std::string& BasePath, const std::string& Path);

bool HasFileExt(const char* FileName, const char* Ext);

#endif
84 changes: 61 additions & 23 deletions Src/beebwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ using std::max;
#include "6502core.h"
#include "disc8271.h"
#include "disc1770.h"
#include "DiscInfo.h"
#include "SysVia.h"
#include "uservia.h"
#include "video.h"
Expand Down Expand Up @@ -119,11 +120,7 @@ LEDColour DiscLedColour = LEDColour::Red;

// FDC Board extension DLL variables
HMODULE hFDCBoard;

EDCB ExtBoard={0,0,NULL};
bool DiscLoaded[2] = { false, false }; // Set to true when a disc image has been loaded
char CDiscName[2][256]; // Filename of disc current in drive 0 and 1
DiscType CDiscType[2]; // Current disc types
char FDCDLL[256]={0};

const char *WindowTitle = "BeebEm - BBC Model B / Master 128 Emulator";
Expand Down Expand Up @@ -586,11 +583,18 @@ void BeebWin::ResetBeebSystem(Model NewModelType, bool LoadRoms)
Reset1770();
AtoDInit();
SetRomMenu();
FreeDiscImage(0);
// Keep the disc images loaded
FreeDiscImage(1);
Close1770Disc(0);
Close1770Disc(1);

char szDiscName[2][MAX_PATH];
strcpy(szDiscName[0], DiscInfo[0].FileName);
strcpy(szDiscName[1], DiscInfo[1].FileName);

DiscType Type[2];
Type[0] = DiscInfo[0].Type;
Type[1] = DiscInfo[1].Type;

EjectDiscImage(0);
EjectDiscImage(1);

if (SCSIDriveEnabled) SCSIReset();
if (SCSIDriveEnabled) SASIReset();
if (IDEDriveEnabled) IDEReset();
Expand All @@ -602,20 +606,54 @@ void BeebWin::ResetBeebSystem(Model NewModelType, bool LoadRoms)
LoadFDC(NULL, false);
}

if (MachineType != Model::Master128 && NativeFDC) {
// Keep the disc images loaded

if (MachineType != Model::Master128 && NativeFDC)
{
// 8271 disc
if (DiscLoaded[0] && CDiscType[0] == DiscType::SSD) LoadSimpleDiscImage(CDiscName[0], 0, 0, 80);
if (DiscLoaded[0] && CDiscType[0] == DiscType::DSD) LoadSimpleDSDiscImage(CDiscName[0], 0, 80);
if (DiscLoaded[0] && CDiscType[0] == DiscType::FSD) LoadFSDDiscImage(CDiscName[0], 0);
if (DiscLoaded[1] && CDiscType[1] == DiscType::SSD) LoadSimpleDiscImage(CDiscName[1], 1, 0, 80);
if (DiscLoaded[1] && CDiscType[1] == DiscType::DSD) LoadSimpleDSDiscImage(CDiscName[1], 1, 80);
if (DiscLoaded[1] && CDiscType[1] == DiscType::FSD) LoadFSDDiscImage(CDiscName[1], 1);
if (szDiscName[0][0] != '\0')
{
if (Type[0] == DiscType::SSD || Type[0] == DiscType::DSD)
{
Load8271DiscImage(szDiscName[0], 0, 80, Type[0]);
}
else if (Type[0] == DiscType::FSD)
{
LoadFSDDiscImage(szDiscName[0], 0);
}
}

if (szDiscName[1][0] != '\0')
{
if (Type[1] == DiscType::SSD || Type[1] == DiscType::DSD)
{
Load8271DiscImage(szDiscName[1], 1, 80, Type[1]);
}
else if (Type[1] == DiscType::FSD)
{
LoadFSDDiscImage(szDiscName[1], 1);
}
}
}

if ((MachineType != Model::Master128 && !NativeFDC) || (MachineType == Model::Master128)) {
if ((MachineType != Model::Master128 && !NativeFDC) || (MachineType == Model::Master128))
{
// 1770 Disc
if (DiscLoaded[0]) Load1770DiscImage(CDiscName[0], 0, CDiscType[0]);
if (DiscLoaded[1]) Load1770DiscImage(CDiscName[1], 1, CDiscType[1]);
if (szDiscName[0][0] != '\0')
{
if (Type[0] != DiscType::FSD)
{
Load1770DiscImage(szDiscName[0], 0, Type[0]);
}
}

if (szDiscName[1][0] != '\0')
{
if (Type[1] != DiscType::FSD)
{
Load1770DiscImage(szDiscName[1], 1, Type[1]);
}
}
}
}

Expand Down Expand Up @@ -4723,7 +4761,7 @@ void BeebWin::HandleCommandLineFile(int Drive, const char *CmdLineFile)
{
if (NativeFDC)
{
LoadSimpleDSDiscImage(FileName, Drive, 80);
Load8271DiscImage(FileName, Drive, 80, DiscType::DSD);
}
else
{
Expand All @@ -4734,7 +4772,7 @@ void BeebWin::HandleCommandLineFile(int Drive, const char *CmdLineFile)
{
if (NativeFDC)
{
LoadSimpleDiscImage(FileName, Drive, 0, 80);
Load8271DiscImage(FileName, Drive, 80, DiscType::SSD);
}
else
{
Expand All @@ -4756,7 +4794,7 @@ void BeebWin::HandleCommandLineFile(int Drive, const char *CmdLineFile)
{
if (NativeFDC)
{
LoadSimpleDiscImage(FileName, Drive, 0, 80); // Treat like an ssd
Load8271DiscImage(FileName, Drive, 80, DiscType::SSD); // Treat like an ssd
}
else
{
Expand All @@ -4778,7 +4816,7 @@ void BeebWin::HandleCommandLineFile(int Drive, const char *CmdLineFile)
}
else // Model::Master128
{
if (Type == FileType::DSD)
if (Type == FileType::FSD)
{
Load1770DiscImage(FileName, Drive, DiscType::DSD);
}
Expand Down
5 changes: 3 additions & 2 deletions Src/beebwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,15 @@ class BeebWin {
void SetRealTimeTarget(double RealTimeTarget);
void TranslateKeyMapping(void);
bool ReadDisc(int Drive, bool bCheckForPrefs);
void Load1770DiscImage(const char *FileName, int Drive, DiscType Type);
bool Load1770DiscImage(const char *FileName, int Drive, DiscType Type);
bool Load8271DiscImage(const char *FileName, int Drive, int Tracks, DiscType Type);
void LoadTape(void);
void InitJoystick(void);
void ResetJoystick(void);
void RestoreState(void);
void SaveState(void);
void NewDiscImage(int Drive);
void CreateDiscImage(const char *FileName, int DriveNum, int Heads, int Tracks);
void CreateDFSDiscImage(const char *FileName, int Drive, int Heads, int Tracks);
void EjectDiscImage(int Drive);
void ExportDiscFiles(int menuId);
void ImportDiscFiles(int menuId);
Expand Down
Loading

0 comments on commit 5b31437

Please sign in to comment.