flopimg: Fix issues when wrapping in generate_bitstream_from_track which were especially damaging for apple drivers
This commit is contained in:
parent
6d3c4ff49a
commit
5b17570612
@ -1316,92 +1316,142 @@ std::vector<bool> floppy_image_format_t::generate_bitstream_from_track(int track
|
|||||||
return trackbuf;
|
return trackbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start at the write splice
|
class pll {
|
||||||
uint32_t splice = image->get_write_splice_position(track, head, subtrack);
|
private:
|
||||||
int cur_pos = splice;
|
const std::vector<uint32_t> &tbuf;
|
||||||
int cur_entry = 0;
|
int cur_pos;
|
||||||
while(cur_entry < int(tbuf.size())-1 && (tbuf[cur_entry+1] & floppy_image::TIME_MASK) < cur_pos)
|
int cur_entry;
|
||||||
cur_entry++;
|
int period;
|
||||||
|
int period_adjust_base;
|
||||||
|
int min_period;
|
||||||
|
int max_period;
|
||||||
|
int phase_adjust;
|
||||||
|
int freq_hist;
|
||||||
|
bool next_is_first;
|
||||||
|
|
||||||
int period = cell_size;
|
public:
|
||||||
int period_adjust_base = period * 0.05;
|
pll(const std::vector<uint32_t> &_tbuf, int cell_size) : tbuf(_tbuf) {
|
||||||
|
period = cell_size;
|
||||||
|
period_adjust_base = period * 0.05;
|
||||||
|
|
||||||
int min_period = int(cell_size*0.75);
|
min_period = int(cell_size*0.75);
|
||||||
int max_period = int(cell_size*1.25);
|
max_period = int(cell_size*1.25);
|
||||||
int phase_adjust = 0;
|
phase_adjust = 0;
|
||||||
int freq_hist = 0;
|
freq_hist = 0;
|
||||||
|
|
||||||
uint32_t scanned = 0;
|
// Try to go back 16 flux changes from the end of the track, or at most at the start
|
||||||
while(scanned < 200000000) {
|
int flux_to_step = 16;
|
||||||
// Note that only MG_F edges are taken into account, the rest is ignored.
|
cur_entry = tbuf.size()-1;
|
||||||
// The lack of MG_F has been tested for previously.
|
while(cur_entry > 0 && flux_to_step) {
|
||||||
while((tbuf[cur_entry] & floppy_image::MG_MASK) != floppy_image::MG_F) {
|
if((tbuf[cur_entry] & floppy_image::MG_MASK) == floppy_image::MG_F)
|
||||||
cur_entry ++;
|
flux_to_step --;
|
||||||
if(cur_entry == tbuf.size())
|
cur_entry--;
|
||||||
cur_entry = 0;
|
}
|
||||||
|
|
||||||
|
// Go back by half-a-period
|
||||||
|
cur_pos = (tbuf[cur_entry] & floppy_image::TIME_MASK) - period/2;
|
||||||
|
|
||||||
|
// Adjust the entry accordingly
|
||||||
|
while(cur_entry > 0 && (cur_pos > (tbuf[cur_entry] & floppy_image::TIME_MASK)))
|
||||||
|
cur_entry --;
|
||||||
|
|
||||||
|
// Now go to the next flux change from there (the no-MG_F case has been handled earlier)
|
||||||
|
while((tbuf[cur_entry] & floppy_image::MG_MASK) != floppy_image::MG_F)
|
||||||
|
cur_entry ++;
|
||||||
|
|
||||||
|
next_is_first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int edge = tbuf[cur_entry] & floppy_image::TIME_MASK;
|
std::pair<bool, bool> get() {
|
||||||
if(edge < cur_pos)
|
bool bit, first;
|
||||||
edge += 200000000;
|
int edge = tbuf[cur_entry] & floppy_image::TIME_MASK;
|
||||||
int next = cur_pos + period + phase_adjust;
|
if(edge < cur_pos)
|
||||||
scanned += period + phase_adjust;
|
edge += 200000000;
|
||||||
|
int next = cur_pos + period + phase_adjust;
|
||||||
|
|
||||||
if(edge >= next) {
|
if(edge >= next) {
|
||||||
// No transition in the window means 0 and pll in free run mode
|
// No transition in the window means 0 and pll in free run mode
|
||||||
trackbuf.push_back(false);
|
bit = false;
|
||||||
phase_adjust = 0;
|
phase_adjust = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Transition in the window means 1, and the pll is adjusted
|
// Transition in the window means 1, and the pll is adjusted
|
||||||
trackbuf.push_back(true);
|
bit = true;
|
||||||
|
|
||||||
int delta = edge - (next - period/2);
|
int delta = edge - (next - period/2);
|
||||||
|
|
||||||
phase_adjust = 0.65*delta;
|
phase_adjust = 0.65*delta;
|
||||||
|
|
||||||
if(delta < 0) {
|
if(delta < 0) {
|
||||||
if(freq_hist < 0)
|
if(freq_hist < 0)
|
||||||
freq_hist--;
|
freq_hist--;
|
||||||
else
|
else
|
||||||
freq_hist = -1;
|
freq_hist = -1;
|
||||||
} else if(delta > 0) {
|
} else if(delta > 0) {
|
||||||
if(freq_hist > 0)
|
if(freq_hist > 0)
|
||||||
freq_hist++;
|
freq_hist++;
|
||||||
else
|
else
|
||||||
freq_hist = 1;
|
freq_hist = 1;
|
||||||
} else
|
} else
|
||||||
freq_hist = 0;
|
freq_hist = 0;
|
||||||
|
|
||||||
if(freq_hist) {
|
if(freq_hist) {
|
||||||
int afh = freq_hist < 0 ? -freq_hist : freq_hist;
|
int afh = freq_hist < 0 ? -freq_hist : freq_hist;
|
||||||
if(afh > 1) {
|
if(afh > 1) {
|
||||||
int aper = period_adjust_base*delta/period;
|
int aper = period_adjust_base*delta/period;
|
||||||
if(!aper)
|
if(!aper)
|
||||||
aper = freq_hist < 0 ? -1 : 1;
|
aper = freq_hist < 0 ? -1 : 1;
|
||||||
period += aper;
|
period += aper;
|
||||||
|
|
||||||
if(period < min_period)
|
if(period < min_period)
|
||||||
period = min_period;
|
period = min_period;
|
||||||
else if(period > max_period)
|
else if(period > max_period)
|
||||||
period = max_period;
|
period = max_period;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
cur_pos = next;
|
first = next_is_first;
|
||||||
if(cur_pos >= 200000000) {
|
next_is_first = false;
|
||||||
cur_pos -= 200000000;
|
|
||||||
cur_entry = 0;
|
|
||||||
}
|
|
||||||
while(cur_entry < int(tbuf.size())-1 && (tbuf[cur_entry] & floppy_image::TIME_MASK) < cur_pos)
|
|
||||||
cur_entry++;
|
|
||||||
|
|
||||||
// Wrap around
|
cur_pos = next;
|
||||||
if(cur_entry == int(tbuf.size())-1 &&
|
if(cur_pos >= 200000000) {
|
||||||
(tbuf[cur_entry] & floppy_image::TIME_MASK) < cur_pos)
|
cur_pos -= 200000000;
|
||||||
cur_entry = 0;
|
cur_entry = 0;
|
||||||
|
|
||||||
|
if(cur_pos >= period/2)
|
||||||
|
first = true;
|
||||||
|
else
|
||||||
|
next_is_first = true;
|
||||||
|
}
|
||||||
|
while(cur_entry < int(tbuf.size())-1 && (tbuf[cur_entry] & floppy_image::TIME_MASK) < cur_pos)
|
||||||
|
cur_entry++;
|
||||||
|
|
||||||
|
// Wrap around
|
||||||
|
if(cur_entry == int(tbuf.size())-1 &&
|
||||||
|
(tbuf[cur_entry] & floppy_image::TIME_MASK) < cur_pos)
|
||||||
|
cur_entry = 0;
|
||||||
|
|
||||||
|
return std::make_pair(bit, first);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pll cpll(tbuf, cell_size);
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
auto r = cpll.get();
|
||||||
|
if(r.second) {
|
||||||
|
trackbuf.push_back(r.first);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for(;;) {
|
||||||
|
auto r = cpll.get();
|
||||||
|
if(r.second)
|
||||||
|
break;
|
||||||
|
trackbuf.push_back(r.first);
|
||||||
|
}
|
||||||
|
|
||||||
return trackbuf;
|
return trackbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user