Skip to content

Commit b765779

Browse files
committedOct 4, 2022
[#65] Support for Greaseweazle boards (Part 4: Common save logic moved to CCapsBase::SaveTrack method forcing any device to override UploadTrack to receive the data)
1 parent 14a1ef4 commit b765779

File tree

6 files changed

+61
-51
lines changed

6 files changed

+61
-51
lines changed
 

‎Main/src/CapsBase.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,12 @@
927927
return ERROR_SUCCESS;
928928
}
929929

930+
TStdWinError CCapsBase::UploadTrack(TCylinder cyl,THead head,CTrackReader tr) const{
931+
// uploads specified Track to a CAPS-based device (e.g. KryoFlux); returns Windows standard i/o error
932+
ASSERT(FALSE); // override in descendant to send Track to a Device
933+
return ERROR_NOT_SUPPORTED;
934+
}
935+
930936
TStdWinError CCapsBase::VerifyTrack(TCylinder cyl,THead head,const CTrackReaderWriter &trwWritten,bool showDiff,std::unique_ptr<CTrackReaderWriter> *ppOutReadTrack,const volatile bool &cancelled) const{
931937
// verifies specified Track that is assumed to be just written; returns Windows standard i/o error
932938
// - Medium must be known

‎Main/src/CapsBase.h

+2
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@
184184
CCapsBase(PCProperties properties,char realDriveLetter,bool hasEditableSettings,LPCTSTR iniSectionName);
185185

186186
virtual TStdWinError UploadFirmware();
187+
virtual TStdWinError UploadTrack(TCylinder cyl,THead head,CTrackReader tr) const;
187188
void DestroyAllTracks();
188189
TStdWinError VerifyTrack(TCylinder cyl,THead head,const CTrackReaderWriter &trwWritten,bool showDiff,std::unique_ptr<CTrackReaderWriter> *ppOutReadTrack,const volatile bool &cancelled) const;
189190
TStdWinError DetermineMagneticReliabilityByWriting(Medium::TType floppyType,TCylinder cyl,THead head,const volatile bool &cancelled) const;
@@ -205,6 +206,7 @@
205206
TStdWinError SetMediumTypeAndGeometry(PCFormat pFormat,PCSide sideMap,TSector firstSectorNumber) override;
206207
bool EditSettings(bool initialEditing) override;
207208
TStdWinError Reset() override;
209+
TStdWinError SaveTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const override;
208210
CTrackReader ReadTrack(TCylinder cyl,THead head) const override;
209211
TStdWinError WriteTrack(TCylinder cyl,THead head,CTrackReader tr) override;
210212
TStdWinError FormatTrack(TCylinder cyl,THead head,Codec::TType codec,TSector nSectors,PCSectorId bufferId,PCWORD bufferLength,PCFdcStatus bufferFdcStatus,BYTE gap3,BYTE fillerByte,const volatile bool &cancelled) override;

‎Main/src/KryoFluxDevice.cpp

+46-49
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,42 @@
609609
return pb-dataBuffer;
610610
}
611611

612+
TStdWinError CKryoFluxDevice::UploadTrack(TCylinder cyl,THead head,CTrackReader tr) const{
613+
// uploads specified Track to a CAPS-based device (e.g. KryoFlux); returns Windows standard i/o error
614+
EXCLUSIVELY_LOCK_DEVICE();
615+
// - converting the supplied Track to "KFW" data, below streamed directly to KryoFlux
616+
const DWORD nBytesToWrite=TrackToKfw1( tr );
617+
#ifdef _DEBUG
618+
if (false){
619+
CFile f;
620+
::CreateDirectory( _T("r:\\kfw"), nullptr );
621+
TCHAR kfwName[80];
622+
::wsprintf( kfwName, _T("r:\\kfw\\track%02d-%c.bin"), cyl, '0'+head );
623+
f.Open( kfwName, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary|CFile::shareExclusive );
624+
f.Write( dataBuffer, nBytesToWrite );
625+
f.Close();
626+
}
627+
#endif
628+
// - clearing i/o pipes
629+
winusb.ClearIoPipes( KF_EP_BULK_IN, KF_EP_BULK_OUT );
630+
// - streaming the "KFW" data to KryoFlux
631+
SendRequest( TRequest::INDEX_WRITE, 2 ); // waiting for an index?
632+
if (!SetMotorOn() || !SelectHead(head) || !SeekTo(cyl)) // some Drives require motor to be on before seeking Heads
633+
return ERROR_NOT_READY;
634+
SendRequest( TRequest::STREAM, 2 ); // start streaming
635+
TStdWinError err=WriteFull( dataBuffer, nBytesToWrite );
636+
if (err==ERROR_SUCCESS)
637+
do{
638+
if (err=SendRequest( TRequest::RESULT_WRITE ))
639+
break;
640+
}while (::strrchr(device.lastRequestResultMsg,'=')[1]=='9'); // TODO: explain why sometimes instead of '0' a return code is '3' but the Track has been written; is it a timeout? if yes, how to solve it?
641+
SendRequest( TRequest::STREAM, 0 ); // stop streaming
642+
return err;
643+
}
644+
612645
#define ERROR_SAVE_MESSAGE_TEMPLATE _T("Track %02d.%c %s failed")
613646

614-
TStdWinError CKryoFluxDevice::SaveAndVerifyTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const{
647+
TStdWinError CCapsBase::SaveTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const{
615648
// saves the specified Track to the inserted Medium; returns Windows standard i/o error
616649
EXCLUSIVELY_LOCK_THIS_IMAGE();
617650
// - Track must already exist from before
@@ -678,54 +711,27 @@
678711
}
679712
// - pre-compensation of the temporary Track
680713
const CTrackReaderWriter trwCompensated( trw, false );
681-
TStdWinError err;
682714
if (precompensation.methodVersion!=CPrecompensation::None)
683-
if ( err=precompensation.ApplyTo(*this,cyl,head,trwCompensated) )
715+
if (const TStdWinError err=precompensation.ApplyTo( *this, cyl, head, trwCompensated ))
684716
return err;
685717
// - Drive's head calibration
686-
EXCLUSIVELY_LOCK_DEVICE();
687718
if (params.calibrationStepDuringFormatting)
688-
if (std::abs(cyl-lastCalibratedCylinder)>>(BYTE)params.doubleTrackStep>=params.calibrationStepDuringFormatting){
689-
lastCalibratedCylinder=cyl;
690-
SeekHeadsHome();
691-
}
719+
if (std::abs(cyl-lastCalibratedCylinder)>>(BYTE)params.doubleTrackStep>=params.calibrationStepDuringFormatting)
720+
if (const TStdWinError err=SeekHeadsHome())
721+
return err;
722+
else
723+
lastCalibratedCylinder=cyl;
692724
// - writing (and optional verification)
725+
TStdWinError err;
726+
TCHAR msgSavingFailed[80];
727+
::wsprintf( msgSavingFailed, ERROR_SAVE_MESSAGE_TEMPLATE, cyl, '0'+head, _T("saving") );
693728
char nSilentRetrials=4;
694729
do{
695730
if (cancelled)
696731
return ERROR_CANCELLED;
697732
// . consuming one SilentRetrial
698733
nSilentRetrials--;
699-
// . converting the temporary Track to "KFW" data, below streamed directly to KryoFlux
700-
const DWORD nBytesToWrite=TrackToKfw1( trwCompensated );
701-
#ifdef _DEBUG
702-
if (false){
703-
CFile f;
704-
::CreateDirectory( _T("r:\\kfw"), nullptr );
705-
TCHAR kfwName[80];
706-
::wsprintf( kfwName, _T("r:\\kfw\\track%02d-%c.bin"), cyl, '0'+head );
707-
f.Open( kfwName, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary|CFile::shareExclusive );
708-
f.Write( dataBuffer, nBytesToWrite );
709-
f.Close();
710-
}
711-
#endif
712-
// . clearing i/o pipes
713-
winusb.ClearIoPipes( KF_EP_BULK_IN, KF_EP_BULK_OUT );
714-
// . streaming the "KFW" data to KryoFlux
715-
SendRequest( TRequest::INDEX_WRITE, 2 ); // waiting for an index?
716-
if (!SetMotorOn() || !SelectHead(head) || !SeekTo(cyl)) // some Drives require motor to be on before seeking Heads
717-
return ERROR_NOT_READY;
718-
SendRequest( TRequest::STREAM, 2 ); // start streaming
719-
err=WriteFull( dataBuffer, nBytesToWrite );
720-
if (err==ERROR_SUCCESS)
721-
do{
722-
if (err=SendRequest( TRequest::RESULT_WRITE ))
723-
break;
724-
}while (::strrchr(device.lastRequestResultMsg,'=')[1]=='9'); // TODO: explain why sometimes instead of '0' a return code is '3' but the Track has been written; is it a timeout? if yes, how to solve it?
725-
SendRequest( TRequest::STREAM, 0 ); // stop streaming
726-
TCHAR msgSavingFailed[80];
727-
::wsprintf( msgSavingFailed, ERROR_SAVE_MESSAGE_TEMPLATE, cyl, '0'+head, _T("saving") );
728-
if (err) // writing to the device failed
734+
if (err=UploadTrack( cyl, head, trwCompensated )) // writing to the device failed
729735
switch (
730736
nSilentRetrials>0 || cancelled
731737
? IDRETRY
@@ -761,20 +767,11 @@
761767
}while (err!=ERROR_SUCCESS && err!=ERROR_CONTINUE);
762768
// - (successfully) saved - see TODOs
763769
pit->modified=false;
770+
if (err==ERROR_CONTINUE) // if writing errors commanded to ignore ...
771+
err=ERROR_SUCCESS; // ... then the Track has been saved successfully
764772
return err;
765773
}
766774

767-
TStdWinError CKryoFluxDevice::SaveTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const{
768-
// saves the specified Track to the inserted Medium; returns Windows standard i/o error
769-
switch (const TStdWinError err=SaveAndVerifyTrack(cyl,head,cancelled)){
770-
case ERROR_SUCCESS:
771-
case ERROR_CONTINUE: // writing errors ignored
772-
return ERROR_SUCCESS;
773-
default:
774-
return err;
775-
}
776-
}
777-
778775
CImage::CTrackReader CKryoFluxDevice::ReadTrack(TCylinder cyl,THead head) const{
779776
// creates and returns a general description of the specified Track, represented using neutral LogicalTimes
780777
PInternalTrack &rit=internalTracks[cyl][head];

‎Main/src/KryoFluxDevice.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
LPCSTR GetProductName() const;
8686
TStdWinError SamBaCommand(LPCSTR cmd,LPCSTR end) const;
8787
TStdWinError UploadFirmware() override;
88+
TStdWinError UploadTrack(TCylinder cyl,THead head,CTrackReader tr) const override;
8889
DWORD TrackToKfw1(CTrackReader tr) const;
8990
TStdWinError SendRequest(TRequest req,WORD index=0,WORD value=0) const;
9091
int GetLastRequestResult() const;
@@ -95,7 +96,6 @@
9596
bool SetMotorOn(bool on=true) const;
9697
bool SeekTo(TCylinder cyl) const;
9798
bool SelectHead(THead head) const;
98-
TStdWinError SaveAndVerifyTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const;
9999
public:
100100
static const TProperties Properties;
101101

@@ -113,7 +113,6 @@
113113
bool EditSettings(bool initialEditing) override;
114114
TStdWinError Reset() override;
115115
CTrackReader ReadTrack(TCylinder cyl,THead head) const override;
116-
TStdWinError SaveTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const override;
117116
void SetPathName(LPCTSTR lpszPathName,BOOL bAddToMRU=TRUE) override;
118117
};
119118

‎Main/src/SCP.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ formatError: ::SetLastError(ERROR_BAD_FORMAT);
135135
return ERROR_SUCCESS;
136136
}
137137

138+
TStdWinError CSCP::SaveTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const{
139+
// saves the specified Track to the inserted Medium; returns Windows standard i/o error
140+
return ERROR_NOT_SUPPORTED; // individual Track saving is not supported for this kind of Image (OnSaveDocument must be called instead)
141+
}
142+
138143
TStdWinError CSCP::SaveAllModifiedTracks(LPCTSTR lpszPathName,CActionProgress &ap){
139144
// saves all Modified Tracks; returns Windows standard i/o error
140145
CFile fTmp;

‎Main/src/SCP.h

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
CSCP();
1515

1616
BOOL OnOpenDocument(LPCTSTR lpszPathName) override;
17+
TStdWinError SaveTrack(TCylinder cyl,THead head,const volatile bool &cancelled) const;
1718
CTrackReader ReadTrack(TCylinder cyl,THead head) const override;
1819
TStdWinError Reset() override;
1920
};

0 commit comments

Comments
 (0)
Please sign in to comment.