mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-09 00:37:27 +00:00
Ensures generation of random noise if too many zeroes exist on a disk surface.
This commit is contained in:
parent
d2d7ab5d04
commit
9f2f388e5a
@ -12,13 +12,15 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
||||
Drive::Drive(unsigned int input_clock_rate, int revolutions_per_minute, int number_of_heads):
|
||||
Storage::TimedEventLoop(input_clock_rate),
|
||||
rotational_multiplier_(60, revolutions_per_minute),
|
||||
available_heads_(number_of_heads) {
|
||||
available_heads_(number_of_heads),
|
||||
random_source_(static_cast<uint64_t>(arc4random()) | (static_cast<uint64_t>(arc4random()) << 32)) {
|
||||
rotational_multiplier_.simplify();
|
||||
}
|
||||
|
||||
@ -161,10 +163,28 @@ void Drive::get_next_event(const Time &duration_already_passed) {
|
||||
// Grab a new track if not already in possession of one. This will recursively call get_next_event,
|
||||
// supplying a proper duration_already_passed.
|
||||
if(!track_) {
|
||||
random_interval_.set_zero();
|
||||
setup_track();
|
||||
return;
|
||||
}
|
||||
|
||||
// If gain has now been turned up so as to generate noise, generate some noise.
|
||||
if(random_interval_ > Time(0)) {
|
||||
current_event_.type = Track::Event::IndexHole;
|
||||
current_event_.length.length = 2 + (random_source_&1);
|
||||
current_event_.length.clock_rate = 1000000;
|
||||
random_source_ = (random_source_ >> 1) | (random_source_ << 63);
|
||||
|
||||
if(random_interval_ < current_event_.length) {
|
||||
current_event_.length = random_interval_;
|
||||
random_interval_.set_zero();
|
||||
} else {
|
||||
random_interval_ -= current_event_.length;
|
||||
}
|
||||
set_next_event_time_interval(current_event_.length);
|
||||
return;
|
||||
}
|
||||
|
||||
if(track_) {
|
||||
current_event_ = track_->get_next_event();
|
||||
} else {
|
||||
@ -178,6 +198,15 @@ void Drive::get_next_event(const Time &duration_already_passed) {
|
||||
assert(current_event_.length <= Time(1) && current_event_.length >= Time(0));
|
||||
assert(current_event_.length > duration_already_passed);
|
||||
Time interval = (current_event_.length - duration_already_passed) * rotational_multiplier_;
|
||||
|
||||
// An interval greater than 15ms => adjust gain up the point where noise starts happening.
|
||||
// Seed that up and leave a 15ms gap until it starts.
|
||||
const Time safe_gain_period(15, 1000000);
|
||||
if(interval >= safe_gain_period) {
|
||||
random_interval_ = interval - safe_gain_period;
|
||||
interval = safe_gain_period;
|
||||
}
|
||||
|
||||
set_next_event_time_interval(interval);
|
||||
}
|
||||
|
||||
|
@ -199,6 +199,10 @@ class Drive: public Sleeper, public TimedEventLoop {
|
||||
Activity::Observer *observer_ = nullptr;
|
||||
std::string drive_name_;
|
||||
bool announce_motor_led_ = false;
|
||||
|
||||
// A rotating random data source.
|
||||
uint64_t random_source_;
|
||||
Time random_interval_;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user