Skip to content

Commit 877052a

Browse files
committed
Allow new sectors to start in the data region of existing sectors.
Fixes #551. This is important for some copy protection schemes.
1 parent e733dc9 commit 877052a

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

arch/amiga/decoder.cc

+5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ class AmigaDecoder : public AbstractDecoder
7474
return sectors;
7575
}
7676

77+
bool recordsSeekable() const override
78+
{
79+
return false;
80+
}
81+
7782
private:
7883
const AmigaDecoderProto& _config;
7984
nanoseconds_t _clock;

lib/decoders/decoders.cc

+23-14
Original file line numberDiff line numberDiff line change
@@ -89,40 +89,42 @@ std::shared_ptr<const TrackDataFlux> AbstractDecoder::decodeToSectors(
8989

9090
/* Read the sector record. */
9191

92-
Fluxmap::Position before = fmr.tell();
92+
Fluxmap::Position before_sector = fmr.tell();
9393
decodeSectorRecord();
94-
Fluxmap::Position after = fmr.tell();
95-
pushRecord(before, after);
94+
Fluxmap::Position after_sector = fmr.tell();
95+
pushRecord(before_sector, after_sector);
9696

9797
if (_sector->status != Sector::DATA_MISSING)
9898
{
99-
_sector->position = before.bytes;
100-
_sector->dataStartTime = before.ns();
101-
_sector->dataEndTime = after.ns();
99+
_sector->position = before_sector.bytes;
100+
_sector->dataStartTime = before_sector.ns();
101+
_sector->dataEndTime = after_sector.ns();
102102
}
103103
else
104104
{
105105
/* The data is in a separate record. */
106+
Fluxmap::Position before_data = before_sector;
107+
Fluxmap::Position after_data = after_sector;
106108

107109
for (;;)
108110
{
109-
_sector->headerStartTime = before.ns();
110-
_sector->headerEndTime = after.ns();
111+
_sector->headerStartTime = before_data.ns();
112+
_sector->headerEndTime = after_data.ns();
111113

112114
_sector->clock = advanceToNextRecord();
113115
if (fmr.eof() || !_sector->clock)
114116
break;
115117

116-
before = fmr.tell();
118+
before_data = fmr.tell();
117119
decodeDataRecord();
118-
after = fmr.tell();
120+
after_data = fmr.tell();
119121

120122
if (_sector->status != Sector::DATA_MISSING)
121123
{
122-
_sector->position = before.bytes;
123-
_sector->dataStartTime = before.ns();
124-
_sector->dataEndTime = after.ns();
125-
pushRecord(before, after);
124+
_sector->position = before_data.bytes;
125+
_sector->dataStartTime = before_data.ns();
126+
_sector->dataEndTime = after_data.ns();
127+
pushRecord(before_data, after_data);
126128
break;
127129
}
128130

@@ -131,6 +133,13 @@ std::shared_ptr<const TrackDataFlux> AbstractDecoder::decodeToSectors(
131133
}
132134
}
133135

136+
/* Allow decode of overlapping records.
137+
* Note that this seeks to after the sector record, but before
138+
* the data record, so it relies on a lone data record being
139+
* ignored. */
140+
if (this->recordsSeekable())
141+
fmr.seek(after_sector);
142+
134143
if (_sector->status != Sector::MISSING)
135144
_trackdata->sectors.push_back(_sector);
136145
}

lib/decoders/decoders.h

+8
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ class AbstractDecoder
9191

9292
virtual std::set<unsigned> requiredSectors(const Location& location) const;
9393

94+
/* Indicates whether records have a unique start pattern, e.g. whether
95+
* must be read contiguously (Amiga) or can be search for from any
96+
* position (IBM). */
97+
virtual bool recordsSeekable() const
98+
{
99+
return true;
100+
}
101+
94102
protected:
95103
virtual void beginTrack(){};
96104
virtual nanoseconds_t advanceToNextRecord() = 0;

0 commit comments

Comments
 (0)