1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +00:00

Ensures generation of random noise if too many zeroes exist on a disk surface.

This commit is contained in:
Thomas Harte 2018-05-14 19:17:34 -04:00
parent d2d7ab5d04
commit 9f2f388e5a
2 changed files with 34 additions and 1 deletions

View File

@ -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);
}

View File

@ -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_;
};