Make the disk exerciser work, and fix a pile of bugs.

This commit is contained in:
David Given
2025-10-31 01:20:06 +01:00
parent 121cdefd09
commit 8fdcae5d1c
6 changed files with 79 additions and 19 deletions

View File

@@ -339,7 +339,7 @@ static void wtClearDiskData()
[]
{
::wtImage = nullptr;
::disk = nullptr;
::disk = std::make_shared<Disk>();
});
}
@@ -805,4 +805,4 @@ void Datastore::createBlankImage()
throw;
}
});
}
}

View File

@@ -33,7 +33,6 @@ public:
static std::shared_ptr<const DiskLayout> getDiskLayout();
static void onLogMessage(const AnyLogMessage& message);
/* Begins a transation. Rebuilds the configuration. */
static void reset();
static void beginRead(bool rereadBadSectors);
static void beginWrite();

View File

@@ -1,37 +1,70 @@
#include <hex/api/content_registry/user_interface.hpp>
#include <hex/api/theme_manager.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/logger.hpp>
#include <fonts/vscode_icons.hpp>
#include <fonts/tabler_icons.hpp>
#include <fmt/format.h>
#include "lib/core/globals.h"
#include "lib/config/config.h"
#include "lib/data/disk.h"
#include "lib/data/layout.h"
#include "lib/data/sector.h"
#include "lib/config/proto.h"
#include "globals.h"
#include "exerciserview.h"
#include "datastore.h"
#include "utils.h"
#include "lib/usb/usb.h"
#include <implot.h>
#include <implot_internal.h>
using namespace hex;
static DiskLayout::LayoutBounds physicalBounds = {-1, -1, -1, -1};
static int selectedDrive;
static int selectedHead;
static int selectedCylinder;
ExerciserView::ExerciserView():
View::Modal("fluxengine.view.exerciser.name", ICON_VS_DEBUG)
{
}
void ExerciserView::onOpen()
{
Datastore::reset();
Datastore::runOnWorkerThread(
[]
{
auto tracks =
parseCylinderHeadsString(globalConfig()->drive().tracks());
auto bounds = DiskLayout::getBounds(std::views::all(tracks));
hex::TaskManager::doLaterOnce(
[=]
{
::physicalBounds = bounds;
selectedDrive = 0;
selectedHead = bounds.minHead;
selectedCylinder = bounds.minCylinder;
});
});
}
void ExerciserView::onClose()
{
physicalBounds.minCylinder = physicalBounds.maxCylinder =
physicalBounds.minHead = physicalBounds.maxHead = -1;
}
void ExerciserView::drawContent()
{
static int selectedDrive = 0;
static int selectedTrack = 0;
if (physicalBounds.minCylinder == -1)
return;
const float label_width = ImGui::GetFontSize() * 6;
ImGui::PushItemWidth(-label_width);
DEFER(ImGui::PopItemWidth());
int oldCylinder = selectedCylinder;
ImGui::SliderInt("fluxengine.view.exerciser.drive"_lang,
&selectedDrive,
0,
@@ -39,9 +72,9 @@ void ExerciserView::drawContent()
"%d",
ImGuiSliderFlags_None);
ImGui::SliderInt("fluxengine.view.exerciser.cylinder"_lang,
&selectedTrack,
0,
82,
&selectedCylinder,
physicalBounds.minCylinder,
physicalBounds.maxCylinder,
"%d",
ImGuiSliderFlags_None);
@@ -55,16 +88,29 @@ void ExerciserView::drawContent()
ImGui::TableNextColumn();
if (ImGui::Button("fluxengine.view.exerciser.nudgeDown"_lang,
{ImGui::GetContentRegionAvail().x, 0}))
selectedTrack--;
selectedCylinder--;
ImGui::TableNextColumn();
if (ImGui::Button("fluxengine.view.exerciser.reset"_lang,
{ImGui::GetContentRegionAvail().x, 0}))
selectedTrack = 0;
selectedCylinder = 0;
ImGui::TableNextColumn();
if (ImGui::Button("fluxengine.view.exerciser.nudgeUp"_lang,
{ImGui::GetContentRegionAvail().x, 0}))
selectedTrack++;
selectedCylinder++;
}
selectedTrack = std::clamp(selectedTrack, 0, 82);
selectedCylinder = std::clamp(selectedCylinder,
physicalBounds.minCylinder,
physicalBounds.maxCylinder);
if (selectedCylinder != oldCylinder)
{
Datastore::runOnWorkerThread(
[=]
{
usbSetDrive(
selectedDrive, false, globalConfig()->drive().index_mode());
usbSeek(selectedCylinder);
});
}
}

View File

@@ -10,6 +10,11 @@ public:
void drawContent() override;
protected:
void onOpen() override;
void onClose() override;
public:
[[nodiscard]] bool shouldDraw() const override
{
return true;
@@ -18,5 +23,14 @@ public:
{
return false;
}
};
ImVec2 getMinSize() const override
{
return {800, 100};
}
int getWindowFlags() const override
{
return ImGuiWindowFlags_AlwaysAutoResize;
}
};

View File

@@ -141,6 +141,8 @@ static void drawPhysicalMap(unsigned minPhysicalCylinder,
{
int numPhysicalCylinders = maxPhysicalCylinder - minPhysicalCylinder + 1;
int numPhysicalHeads = maxPhysicalHead - minPhysicalHead + 1;
if (!numPhysicalCylinders || !numPhysicalHeads)
return;
auto originalFontSize = ImGui::GetFontSize();
if (ImGui::BeginTable("physicalMap",
@@ -225,6 +227,8 @@ static void drawLogicalMap(unsigned minPhysicalCylinder,
auto originalFontSize = ImGui::GetFontSize();
int numPhysicalCylinders = maxPhysicalCylinder - minPhysicalCylinder + 1;
int numPhysicalHeads = maxPhysicalHead - minPhysicalHead + 1;
if (!numPhysicalCylinders || !numPhysicalHeads)
return;
if (ImGui::BeginTable("logicalMap",
numPhysicalCylinders + 1,
@@ -334,8 +338,6 @@ void SummaryView::drawContent()
maxPhysicalCylinder,
minPhysicalHead,
maxPhysicalHead] = diskLayout->getPhysicalBounds();
int numPhysicalCylinders = maxPhysicalCylinder - minPhysicalCylinder + 1;
int numPhysicalHeads = maxPhysicalHead - minPhysicalHead + 1;
if (disk)
{

View File

@@ -20,4 +20,3 @@ public:
return true;
}
};