From a413ae11cbcdc7d82bf947b8ea34c6f217be0893 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 4 Jun 2019 22:13:00 -0400 Subject: [PATCH] Makes some sort of first attempt at having the IWM read. --- Components/DiskII/IWM.cpp | 44 +++++++++++++++++++++++++- Components/DiskII/IWM.hpp | 10 +++++- Machines/Apple/Macintosh/Macintosh.cpp | 29 ++++++++++++++--- Machines/Apple/Macintosh/SonyDrive.cpp | 7 +++- 4 files changed, 82 insertions(+), 8 deletions(-) diff --git a/Components/DiskII/IWM.cpp b/Components/DiskII/IWM.cpp index ff503a0ff..9e7f29555 100644 --- a/Components/DiskII/IWM.cpp +++ b/Components/DiskII/IWM.cpp @@ -59,8 +59,12 @@ uint8_t IWM::read(int address) { return 0xff; case ENABLE: /* Read data register. */ + if(data_register_ & 0x80) { + printf("[%02x] ", data_register_); + data_register_ = 0; + } printf("Reading data register\n"); - return 0x00; + return data_register_; case Q6: case Q6|ENABLE: { /* @@ -257,11 +261,49 @@ void IWM::run_for(const Cycles cycles) { } // Activity otherwise depends on mode and motor state. + const bool run_disk = drive_motor_on_ && drives_[active_drive_]; + int integer_cycles = cycles.as_int(); switch(state_ & (Q6 | Q7 | ENABLE)) { + case ENABLE: // i.e. read mode. + while(integer_cycles--) { + if(run_disk) { + drives_[active_drive_]->run_for(Cycles(1)); + } + ++cycles_since_shift_; + if(cycles_since_shift_ == bit_length_ + Cycles(2)) { + propose_shift(0); + } + } + break; + + default: + if(run_disk) drives_[active_drive_]->run_for(cycles); + break; } } +void IWM::process_event(const Storage::Disk::Track::Event &event) { + switch(event.type) { + case Storage::Disk::Track::Event::IndexHole: return; + case Storage::Disk::Track::Event::FluxTransition: + propose_shift(1); + break; + } +} + +void IWM::propose_shift(uint8_t bit) { + // TODO: synchronous mode. + shift_register_ = uint8_t((shift_register_ << 1) | bit); + if(shift_register_ & 0x80) { + printf("%02x -> data\n", shift_register_); + data_register_ = shift_register_; + shift_register_ = 0; + } + cycles_since_shift_ = Cycles(0); +} + void IWM::set_drive(int slot, Storage::Disk::Drive *drive) { drives_[slot] = drive; + drive->set_event_delegate(this); } diff --git a/Components/DiskII/IWM.hpp b/Components/DiskII/IWM.hpp index 764353f81..cf3f5f670 100644 --- a/Components/DiskII/IWM.hpp +++ b/Components/DiskII/IWM.hpp @@ -16,7 +16,8 @@ namespace Apple { -class IWM { +class IWM: + public Storage::Disk::Drive::EventDelegate { public: IWM(int clock_rate); @@ -42,8 +43,12 @@ class IWM { void set_drive(int slot, Storage::Disk::Drive *drive); private: + // Storage::Disk::Drive::EventDelegate. + void process_event(const Storage::Disk::Track::Event &event) override; + const int clock_rate_; + uint8_t data_register_ = 0; uint8_t mode_ = 0; bool read_write_ready_ = true; bool write_overran_ = false; @@ -58,6 +63,9 @@ class IWM { void access(int address); + uint8_t shift_register_ = 0; + void propose_shift(uint8_t bit); + Cycles cycles_since_shift_; Cycles bit_length_; }; diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 6b640c4e2..32dbad2f9 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -18,6 +18,7 @@ #include "Video.hpp" #include "../../CRTMachine.hpp" +#include "../../MediaTarget.hpp" //#define LOG_TRACE @@ -41,9 +42,12 @@ namespace Macintosh { template class ConcreteMachine: public Machine, public CRTMachine::Machine, + public MediaTarget::Machine, public CPU::MC68000::BusHandler { public: - ConcreteMachine(const ROMMachine::ROMFetcher &rom_fetcher) : + using Target = Analyser::Static::Macintosh::Target; + + ConcreteMachine(const Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : mc68000_(*this), iwm_(CLOCK_RATE), video_(ram_, audio_, drive_speed_accumulator_), @@ -97,6 +101,9 @@ template class ConcreteMachin // The Mac runs at 7.8336mHz. set_clock_rate(double(CLOCK_RATE)); audio_.speaker.set_input_rate(float(CLOCK_RATE)); + + // Insert any supplied media. + insert_media(target.media); } ~ConcreteMachine() { @@ -312,6 +319,18 @@ template class ConcreteMachin video_.set_use_alternate_buffers(use_alternate_screen_buffer, use_alternate_audio_buffer); } + bool insert_media(const Analyser::Static::Media &media) override { + if(media.disks.empty()) + return false; + + // TODO: shouldn't allow disks to be replaced like this, as the Mac + // uses software eject. Will need to expand messaging ability of + // insert_media. + drives_[0].set_disk(media.disks[0]); + + return true; + } + private: struct IWM { IWM(int clock_rate) : iwm(clock_rate) {} @@ -465,10 +484,10 @@ Machine *Machine::Macintosh(const Analyser::Static::Target *target, const ROMMac using Model = Analyser::Static::Macintosh::Target::Model; switch(mac_target->model) { default: - case Model::Mac128k: return new ConcreteMachine(rom_fetcher); - case Model::Mac512k: return new ConcreteMachine(rom_fetcher); - case Model::Mac512ke: return new ConcreteMachine(rom_fetcher); - case Model::MacPlus: return new ConcreteMachine(rom_fetcher); + case Model::Mac128k: return new ConcreteMachine(*mac_target, rom_fetcher); + case Model::Mac512k: return new ConcreteMachine(*mac_target, rom_fetcher); + case Model::Mac512ke: return new ConcreteMachine(*mac_target, rom_fetcher); + case Model::MacPlus: return new ConcreteMachine(*mac_target, rom_fetcher); } } diff --git a/Machines/Apple/Macintosh/SonyDrive.cpp b/Machines/Apple/Macintosh/SonyDrive.cpp index b691cc8f6..6a538496e 100644 --- a/Machines/Apple/Macintosh/SonyDrive.cpp +++ b/Machines/Apple/Macintosh/SonyDrive.cpp @@ -11,7 +11,12 @@ using namespace Apple::Macintosh; SonyDrive::SonyDrive(int input_clock_rate, bool is_800k) : - Storage::Disk::Drive(static_cast(input_clock_rate), is_800k ? 2 : 1), is_800k_(is_800k) {} + Storage::Disk::Drive(static_cast(input_clock_rate), is_800k ? 2 : 1), is_800k_(is_800k) { + // Start with a valid rotation speed. + if(is_800k) { + set_rotation_speed(393.3807f); + } +} void SonyDrive::did_step(Storage::Disk::HeadPosition to_position) { // The 800kb drive automatically selects rotation speed as a function of