mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Implements latest advocated MC3470 behaviour.
This commit is contained in:
parent
d065d6d98f
commit
aed61f6251
@ -250,6 +250,15 @@ void Drive::run_for(const Cycles cycles) {
|
|||||||
// MARK: - Track timed event loop
|
// MARK: - Track timed event loop
|
||||||
|
|
||||||
void Drive::get_next_event(float duration_already_passed) {
|
void Drive::get_next_event(float duration_already_passed) {
|
||||||
|
/*
|
||||||
|
Quick word on random-bit generation logic below; it seeks to obey the following logic:
|
||||||
|
if there is a gap of 15µs between recorded bits, start generating flux transitions
|
||||||
|
at random intervals thereafter, unless and until one is within 5µs of the next real transition.
|
||||||
|
|
||||||
|
This behaviour is based on John Morris' observations of an MC3470, as described in his WOZ
|
||||||
|
file format documentation — https://applesaucefdc.com/woz/reference2/
|
||||||
|
*/
|
||||||
|
|
||||||
if(!disk_) {
|
if(!disk_) {
|
||||||
current_event_.type = Track::Event::IndexHole;
|
current_event_.type = Track::Event::IndexHole;
|
||||||
current_event_.length = 1.0f;
|
current_event_.length = 1.0f;
|
||||||
@ -268,17 +277,18 @@ void Drive::get_next_event(float duration_already_passed) {
|
|||||||
// If gain has now been turned up so as to generate noise, generate some noise.
|
// If gain has now been turned up so as to generate noise, generate some noise.
|
||||||
if(random_interval_ > 0.0f) {
|
if(random_interval_ > 0.0f) {
|
||||||
current_event_.type = Track::Event::FluxTransition;
|
current_event_.type = Track::Event::FluxTransition;
|
||||||
current_event_.length = float(2 + (random_source_&1)) / 1000000.0f;
|
current_event_.length = float(2 + (random_source_&1)) / 1'000'000.0f;
|
||||||
random_source_ = (random_source_ >> 1) | (random_source_ << 63);
|
random_source_ = (random_source_ >> 1) | (random_source_ << 63);
|
||||||
|
|
||||||
if(random_interval_ < current_event_.length) {
|
// If this random transition is closer than 5µs to the next real bit,
|
||||||
current_event_.length = random_interval_;
|
// discard it.
|
||||||
|
if(random_interval_ < current_event_.length - 5.0f / 1'000'000.f) {
|
||||||
random_interval_ = 0.0f;
|
random_interval_ = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
random_interval_ -= current_event_.length;
|
random_interval_ -= current_event_.length;
|
||||||
|
set_next_event_time_interval(current_event_.length);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
set_next_event_time_interval(current_event_.length);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(track_) {
|
if(track_) {
|
||||||
@ -299,9 +309,9 @@ void Drive::get_next_event(float duration_already_passed) {
|
|||||||
// convert it into revolutions per second; this is achieved by multiplying by rotational_multiplier_
|
// convert it into revolutions per second; this is achieved by multiplying by rotational_multiplier_
|
||||||
float interval = std::max((current_event_.length - duration_already_passed) * rotational_multiplier_, 0.0f);
|
float interval = std::max((current_event_.length - duration_already_passed) * rotational_multiplier_, 0.0f);
|
||||||
|
|
||||||
// An interval greater than 15ms => adjust gain up the point where noise starts happening.
|
// An interval greater than 15µs => adjust gain up the point where noise starts happening.
|
||||||
// Seed that up and leave a 15ms gap until it starts.
|
// Seed that up and leave a 15µs gap until it starts.
|
||||||
constexpr float safe_gain_period = 15.0f / 1000000.0f;
|
constexpr float safe_gain_period = 15.0f / 1'000'000.0f;
|
||||||
if(interval >= safe_gain_period) {
|
if(interval >= safe_gain_period) {
|
||||||
random_interval_ = interval - safe_gain_period;
|
random_interval_ = interval - safe_gain_period;
|
||||||
interval = safe_gain_period;
|
interval = safe_gain_period;
|
||||||
|
Loading…
Reference in New Issue
Block a user