2018-04-21 21:33:42 +00:00
|
|
|
//
|
|
|
|
// DiskII.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 20/04/2018.
|
|
|
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef DiskII_hpp
|
|
|
|
#define DiskII_hpp
|
|
|
|
|
|
|
|
#include "../../ClockReceiver/ClockReceiver.hpp"
|
2018-04-29 21:51:10 +00:00
|
|
|
#include "../../ClockReceiver/Sleeper.hpp"
|
2018-04-24 15:29:05 +00:00
|
|
|
|
2018-04-25 02:44:45 +00:00
|
|
|
#include "../../Storage/Disk/Disk.hpp"
|
|
|
|
#include "../../Storage/Disk/Drive.hpp"
|
|
|
|
|
2018-05-11 02:17:13 +00:00
|
|
|
#include "../../Activity/Observer.hpp"
|
|
|
|
|
2018-05-10 02:03:59 +00:00
|
|
|
#include <array>
|
2018-04-21 21:33:42 +00:00
|
|
|
#include <cstdint>
|
2018-04-24 15:29:05 +00:00
|
|
|
#include <vector>
|
2018-04-21 21:33:42 +00:00
|
|
|
|
|
|
|
namespace Apple {
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Provides an emulation of the Apple Disk II.
|
|
|
|
*/
|
2018-04-29 21:51:10 +00:00
|
|
|
class DiskII:
|
|
|
|
public Storage::Disk::Drive::EventDelegate,
|
|
|
|
public Sleeper::SleepObserver,
|
|
|
|
public Sleeper {
|
2018-04-21 21:33:42 +00:00
|
|
|
public:
|
2018-04-25 02:44:45 +00:00
|
|
|
DiskII();
|
|
|
|
|
2018-05-09 02:05:43 +00:00
|
|
|
void set_register(int address, uint8_t value);
|
|
|
|
uint8_t get_register(int address);
|
|
|
|
|
|
|
|
void run_for(const Cycles cycles);
|
|
|
|
void set_state_machine(const std::vector<uint8_t> &);
|
|
|
|
|
|
|
|
void set_disk(const std::shared_ptr<Storage::Disk::Disk> &disk, int drive);
|
|
|
|
bool is_sleeping() override;
|
|
|
|
|
2018-05-11 02:17:13 +00:00
|
|
|
void set_activity_observer(Activity::Observer *observer);
|
|
|
|
|
2018-05-09 02:05:43 +00:00
|
|
|
private:
|
2018-04-21 21:33:42 +00:00
|
|
|
enum class Control {
|
|
|
|
P0, P1, P2, P3,
|
|
|
|
Motor,
|
|
|
|
};
|
|
|
|
enum class Mode {
|
|
|
|
Read, Write
|
|
|
|
};
|
|
|
|
void set_control(Control control, bool on);
|
|
|
|
void set_mode(Mode mode);
|
|
|
|
void select_drive(int drive);
|
2018-04-24 05:29:36 +00:00
|
|
|
void set_data_register(uint8_t value);
|
2018-04-21 21:33:42 +00:00
|
|
|
uint8_t get_shift_register();
|
|
|
|
|
2018-05-09 02:05:43 +00:00
|
|
|
uint8_t trigger_address(int address, uint8_t value);
|
2018-04-25 02:44:45 +00:00
|
|
|
void process_event(const Storage::Disk::Track::Event &event) override;
|
2018-04-29 21:51:10 +00:00
|
|
|
void set_component_is_sleeping(Sleeper *component, bool is_sleeping) override;
|
2018-04-25 02:44:45 +00:00
|
|
|
|
2018-04-24 05:29:36 +00:00
|
|
|
uint8_t state_ = 0;
|
2018-04-24 15:29:05 +00:00
|
|
|
uint8_t inputs_ = 0;
|
2018-04-24 05:29:36 +00:00
|
|
|
uint8_t shift_register_ = 0;
|
|
|
|
uint8_t data_register_ = 0;
|
|
|
|
|
2018-04-25 02:44:45 +00:00
|
|
|
int stepper_mask_ = 0;
|
|
|
|
int stepper_position_ = 0;
|
|
|
|
|
2018-04-24 05:29:36 +00:00
|
|
|
bool is_write_protected();
|
2018-05-10 02:03:59 +00:00
|
|
|
std::array<uint8_t, 256> state_machine_;
|
2018-04-25 02:44:45 +00:00
|
|
|
Storage::Disk::Drive drives_[2];
|
2018-04-29 21:51:10 +00:00
|
|
|
bool drive_is_sleeping_[2];
|
|
|
|
bool controller_can_sleep_ = false;
|
2018-04-25 02:44:45 +00:00
|
|
|
int active_drive_ = 0;
|
2018-04-29 21:51:10 +00:00
|
|
|
|
|
|
|
void set_controller_can_sleep();
|
2018-04-21 21:33:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* DiskII_hpp */
|