Skip to content

Commit

Permalink
[#64] Internal FDD improvements and bugfixes (Part 7: Allowing for ma…
Browse files Browse the repository at this point in the history
…nual head calibration during dumping)
  • Loading branch information
tomas-nestorovic committed Nov 7, 2021
1 parent 1cab37b commit 8d7507b
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Main/src/FDD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,11 @@ error: switch (const TStdWinError err=::GetLastError()){
return Revolution::INFINITY;
}

TStdWinError CFDD::SeekHeadsHome(){
// attempts to send Heads "home"; returns Windows standard i/o error
return fddHead.SeekHome() ? ERROR_SUCCESS : ::GetLastError();
}

CFDD::PInternalTrack CFDD::__scanTrack__(TCylinder cyl,THead head){
// scans given Track and returns the number of discovered Sectors; returns Null if Track cannot be scanned (e.g. due to an hardware error or "out-of-range" error)
// - attempting to scan the specified Track
Expand Down
1 change: 1 addition & 0 deletions Main/src/FDD.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
TCylinder GetCylinderCount() const override;
THead GetHeadCount() const override;
BYTE GetAvailableRevolutionCount() const override;
TStdWinError SeekHeadsHome() override;
TSector ScanTrack(TCylinder cyl,THead head,Codec::PType pCodec=nullptr,PSectorId bufferId=nullptr,PWORD bufferLength=nullptr,PLogTime startTimesNanoseconds=nullptr,PBYTE pAvgGap3=nullptr) const override;
void GetTrackData(TCylinder cyl,THead head,Revolution::TType rev,PCSectorId bufferId,PCBYTE bufferNumbersOfSectorsToSkip,TSector nSectors,PSectorData *outBufferData,PWORD outBufferLengths,TFdcStatus *outFdcStatuses) override;
TStdWinError MarkSectorAsDirty(RCPhysicalAddress chs,BYTE nSectorsToSkip,PCFdcStatus pFdcStatus) override;
Expand Down
5 changes: 5 additions & 0 deletions Main/src/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,11 @@ namespace Medium{
return 1;
}

TStdWinError CImage::SeekHeadsHome(){
// attempts to send Heads "home"; returns Windows standard i/o error
return ERROR_NOT_SUPPORTED;
}

TSector CImage::GetCountOfHealthySectors(TCylinder cyl,THead head) const{
// returns the number of Sectors whose data are healthy
EXCLUSIVELY_LOCK_THIS_IMAGE();
Expand Down
1 change: 1 addition & 0 deletions Main/src/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@
THead GetNumberOfFormattedSides(TCylinder cyl) const;
TTrack GetTrackCount() const;
virtual BYTE GetAvailableRevolutionCount() const;
virtual TStdWinError SeekHeadsHome();
virtual TSector ScanTrack(TCylinder cyl,THead head,Codec::PType pCodec=nullptr,PSectorId bufferId=nullptr,PWORD bufferLength=nullptr,PLogTime startTimesNanoseconds=nullptr,PBYTE pAvgGap3=nullptr) const=0;
virtual TLogTime EstimateNanosecondsPerOneByte() const;
TSector GetCountOfHealthySectors(TCylinder cyl,THead head) const;
Expand Down
19 changes: 17 additions & 2 deletions Main/src/Image_Dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@
#define RESOLVE_EXCLUDE_ID IDIGNORE
#define RESOLVE_EXCLUDE_UNKNOWN IDCONTINUE

#define RETRY_OPTIONS_COUNT 2

#define NO_STATUS_ERROR _T("- no error\r\n")

static UINT AFX_CDECL __dump_thread__(PVOID _pCancelableAction){
Expand All @@ -174,6 +176,7 @@
TPhysicalAddress chs;
TTrack track;
bool trackWriteable; // Track can be written at once using CImage::WriteTrack
bool canCalibrateHeads;
BYTE nTrials;
struct{
WORD automaticallyAcceptedErrors;
Expand All @@ -185,6 +188,7 @@
} exclusion;
} p;
::ZeroMemory(&p,sizeof(p));
p.canCalibrateHeads=dp.source->SeekHeadsHome()!=ERROR_NOT_SUPPORTED;
const bool targetSupportsTrackWriting=dp.target->WriteTrack(0,0,CImage::CTrackReaderWriter::Invalid)!=ERROR_NOT_SUPPORTED;
const Utils::CByteIdentity sectorIdAndPositionIdentity;
TPhysicalAddress chsPrev=TPhysicalAddress::Invalid;
Expand Down Expand Up @@ -303,17 +307,28 @@
resolveActions[4].menuItemFlags=MF_GRAYED*( rFdcStatus.DescribesMissingDam() || !rFdcStatus.DescribesIdFieldCrcError()&&!rFdcStatus.DescribesDataFieldCrcError() ); // enabled only if either ID or Data field with error
ConvertDlgButtonToSplitButton( IDNO, resolveActions, RESOLVE_OPTIONS_COUNT );
EnableDlgItem( IDNO, dynamic_cast<CImageRaw *>(dp.target.get())==nullptr ); // recovering errors is allowed only if the Target Image can accept them
// > converting the "Retry" button to a SplitButton
static constexpr Utils::TSplitButtonAction RetryActions[RETRY_OPTIONS_COUNT]={
{ IDRETRY, _T("Retry") },
{ ID_HEAD, _T("Calibrate head and retry"), MF_GRAYED*!rp.canCalibrateHeads },
};
ConvertDlgButtonToSplitButton( IDRETRY, RetryActions, RETRY_OPTIONS_COUNT );
// > the "Retry" button enabled only if not all Revolutions yet exhausted
EnableDlgItem( IDRETRY, rp.nTrials<dp.source->GetAvailableRevolutionCount() );
const BYTE nRevsAvailable=dp.source->GetAvailableRevolutionCount();
EnableDlgItem( IDRETRY, nRevsAvailable>=Revolution::MAX||rp.nTrials<nRevsAvailable );
}
LRESULT WindowProc(UINT msg,WPARAM wParam,LPARAM lParam) override{
// window procedure
switch (msg){
case WM_COMMAND:
switch (wParam){
case ID_HEAD:
if (const TStdWinError err=dp.source->SeekHeadsHome())
Utils::Information( _T("Can't calibrate"), err, _T("Retrying without calibration.") );
//fallthrough
case IDRETRY:
UpdateData(TRUE);
EndDialog(wParam);
EndDialog(IDRETRY);
return 0;
case ID_ERROR:
rp.acceptance.automaticallyAcceptedErrors|=rFdcStatus.ToWord();
Expand Down

0 comments on commit 8d7507b

Please sign in to comment.