mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-09 05:25:01 +00:00
Sets things up to allow variable rotation rates, and especially Sony 800kb-style self-selecting rates.
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
#include "DriveSpeedAccumulator.hpp"
|
#include "DriveSpeedAccumulator.hpp"
|
||||||
#include "Keyboard.hpp"
|
#include "Keyboard.hpp"
|
||||||
#include "RealTimeClock.hpp"
|
#include "RealTimeClock.hpp"
|
||||||
|
#include "SonyDrive.hpp"
|
||||||
#include "Video.hpp"
|
#include "Video.hpp"
|
||||||
|
|
||||||
#include "../../CRTMachine.hpp"
|
#include "../../CRTMachine.hpp"
|
||||||
@@ -47,7 +48,11 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
iwm_(CLOCK_RATE),
|
iwm_(CLOCK_RATE),
|
||||||
video_(ram_, audio_, drive_speed_accumulator_),
|
video_(ram_, audio_, drive_speed_accumulator_),
|
||||||
via_(via_port_handler_),
|
via_(via_port_handler_),
|
||||||
via_port_handler_(*this, clock_, keyboard_, video_, audio_, iwm_) {
|
via_port_handler_(*this, clock_, keyboard_, video_, audio_, iwm_),
|
||||||
|
drives_{
|
||||||
|
{CLOCK_RATE, model >= Analyser::Static::Macintosh::Target::Model::Mac512ke},
|
||||||
|
{CLOCK_RATE, model >= Analyser::Static::Macintosh::Target::Model::Mac512ke}
|
||||||
|
} {
|
||||||
|
|
||||||
// Select a ROM name and determine the proper ROM and RAM sizes
|
// Select a ROM name and determine the proper ROM and RAM sizes
|
||||||
// based on the machine model.
|
// based on the machine model.
|
||||||
@@ -85,6 +90,10 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
roms[0]->resize(rom_size);
|
roms[0]->resize(rom_size);
|
||||||
Memory::PackBigEndian16(*roms[0], rom_);
|
Memory::PackBigEndian16(*roms[0], rom_);
|
||||||
|
|
||||||
|
// Attach the drives to the IWM.
|
||||||
|
iwm_.iwm.set_drive(0, &drives_[0]);
|
||||||
|
iwm_.iwm.set_drive(1, &drives_[1]);
|
||||||
|
|
||||||
// The Mac runs at 7.8336mHz.
|
// The Mac runs at 7.8336mHz.
|
||||||
set_clock_rate(double(CLOCK_RATE));
|
set_clock_rate(double(CLOCK_RATE));
|
||||||
audio_.speaker.set_input_rate(float(CLOCK_RATE));
|
audio_.speaker.set_input_rate(float(CLOCK_RATE));
|
||||||
@@ -437,6 +446,8 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
bool ROM_is_overlay_ = true;
|
bool ROM_is_overlay_ = true;
|
||||||
int phase_ = 1;
|
int phase_ = 1;
|
||||||
|
|
||||||
|
SonyDrive drives_[2];
|
||||||
|
|
||||||
uint32_t ram_mask_ = 0;
|
uint32_t ram_mask_ = 0;
|
||||||
uint32_t rom_mask_ = 0;
|
uint32_t rom_mask_ = 0;
|
||||||
uint16_t rom_[64*1024];
|
uint16_t rom_[64*1024];
|
||||||
|
32
Machines/Apple/Macintosh/SonyDrive.cpp
Normal file
32
Machines/Apple/Macintosh/SonyDrive.cpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// SonyDrive.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 04/06/2019.
|
||||||
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SonyDrive.hpp"
|
||||||
|
|
||||||
|
using namespace Apple::Macintosh;
|
||||||
|
|
||||||
|
SonyDrive::SonyDrive(int input_clock_rate, bool is_800k) :
|
||||||
|
Storage::Disk::Drive(static_cast<unsigned int>(input_clock_rate), is_800k ? 2 : 1), is_800k_(is_800k) {}
|
||||||
|
|
||||||
|
void SonyDrive::did_step(Storage::Disk::HeadPosition to_position) {
|
||||||
|
// The 800kb drive automatically selects rotation speed as a function of
|
||||||
|
// head position; the 400kb drive doesn't do so.
|
||||||
|
if(is_800k_) {
|
||||||
|
/*
|
||||||
|
Numbers below cribbed from the Kryoflux forums.
|
||||||
|
*/
|
||||||
|
const int zone = to_position.as_int() >> 4;
|
||||||
|
switch(zone) {
|
||||||
|
case 0: set_rotation_speed(393.3807f); break;
|
||||||
|
case 1: set_rotation_speed(429.1723f); break;
|
||||||
|
case 2: set_rotation_speed(472.1435f); break;
|
||||||
|
case 3: set_rotation_speed(524.5672f); break;
|
||||||
|
default: set_rotation_speed(590.1098f); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
Machines/Apple/Macintosh/SonyDrive.hpp
Normal file
34
Machines/Apple/Macintosh/SonyDrive.hpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// SonyDrive.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 04/06/2019.
|
||||||
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SonyDrive_hpp
|
||||||
|
#define SonyDrive_hpp
|
||||||
|
|
||||||
|
#include "../../../Storage/Disk/Drive.hpp"
|
||||||
|
|
||||||
|
namespace Apple {
|
||||||
|
namespace Macintosh {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Models one of the Sony drives found in an original Macintosh,
|
||||||
|
specifically by providing automatic motor speed adjustment if
|
||||||
|
this is an 800kb drive.
|
||||||
|
*/
|
||||||
|
class SonyDrive: public Storage::Disk::Drive {
|
||||||
|
public:
|
||||||
|
SonyDrive(int input_clock_rate, bool is_800k);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void did_step(Storage::Disk::HeadPosition to_position) override;
|
||||||
|
bool is_800k_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SonyDrive_hpp */
|
@@ -36,6 +36,14 @@ Drive::Drive(unsigned int input_clock_rate, int revolutions_per_minute, int numb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Drive::Drive(unsigned int input_clock_rate, int number_of_heads) : Drive(input_clock_rate, 300, number_of_heads) {}
|
||||||
|
|
||||||
|
void Drive::set_rotation_speed(float revolutions_per_minute) {
|
||||||
|
// TODO: probably I should look into
|
||||||
|
// whether doing all this with quotients is really a good idea.
|
||||||
|
rotational_multiplier_ = Time(60.0f / revolutions_per_minute);
|
||||||
|
}
|
||||||
|
|
||||||
Drive::~Drive() {
|
Drive::~Drive() {
|
||||||
if(disk_) disk_->flush_tracks();
|
if(disk_) disk_->flush_tracks();
|
||||||
}
|
}
|
||||||
@@ -75,6 +83,9 @@ void Drive::step(HeadPosition offset) {
|
|||||||
if(head_position_ != old_head_position) {
|
if(head_position_ != old_head_position) {
|
||||||
track_ = nullptr;
|
track_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow a subclass to react, if desired.
|
||||||
|
did_step(head_position_);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Track> Drive::step_to(HeadPosition offset) {
|
std::shared_ptr<Track> Drive::step_to(HeadPosition offset) {
|
||||||
@@ -97,6 +108,10 @@ void Drive::set_head(int head) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Drive::get_head_count() {
|
||||||
|
return available_heads_;
|
||||||
|
}
|
||||||
|
|
||||||
Storage::Time Drive::get_time_into_track() {
|
Storage::Time Drive::get_time_into_track() {
|
||||||
// `result` will initially be amount of time since the index hole was seen as a
|
// `result` will initially be amount of time since the index hole was seen as a
|
||||||
// proportion of a second; convert it into proportion of a rotation, simplify and return.
|
// proportion of a second; convert it into proportion of a rotation, simplify and return.
|
||||||
|
@@ -54,6 +54,11 @@ class Drive: public ClockingHint::Source, public TimedEventLoop {
|
|||||||
*/
|
*/
|
||||||
void set_head(int head);
|
void set_head(int head);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Gets the head count for this disk.
|
||||||
|
*/
|
||||||
|
int get_head_count();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@returns @c true if the inserted disk is read-only or no disk is inserted; @c false otherwise.
|
@returns @c true if the inserted disk is read-only or no disk is inserted; @c false otherwise.
|
||||||
*/
|
*/
|
||||||
@@ -139,7 +144,13 @@ class Drive: public ClockingHint::Source, public TimedEventLoop {
|
|||||||
*/
|
*/
|
||||||
std::shared_ptr<Track> step_to(HeadPosition offset);
|
std::shared_ptr<Track> step_to(HeadPosition offset);
|
||||||
|
|
||||||
void set(Time);
|
/*!
|
||||||
|
Alters the rotational velocity of this drive.
|
||||||
|
*/
|
||||||
|
void set_rotation_speed(float revolutions_per_minute);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void did_step(HeadPosition to_position) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Drives contain an entire disk; from that a certain track
|
// Drives contain an entire disk; from that a certain track
|
||||||
|
Reference in New Issue
Block a user