diff --git a/Components/DiskII/MacintoshDoubleDensityDrive.cpp b/Components/DiskII/MacintoshDoubleDensityDrive.cpp index 5301bd9e2..54444b0c6 100644 --- a/Components/DiskII/MacintoshDoubleDensityDrive.cpp +++ b/Components/DiskII/MacintoshDoubleDensityDrive.cpp @@ -25,10 +25,109 @@ void DoubleDensityDrive::set_enabled(bool) { } void DoubleDensityDrive::set_control_lines(int lines) { + const auto old_state = control_state_; + control_state_ = lines; + + // Catch low-to-high LSTRB transitions. + if((old_state ^ control_state_) & control_state_ & Line::LSTRB) { + switch(control_state_ & (Line::CA1 | Line::CA0 | Line::SEL)) { + default: +// LOG("Unhandled LSTRB"); + break; + + case 0: +// LOG("LSTRB Set stepping direction: " << int(state_ & CA2)); + step_direction_ = (control_state_ & Line::CA2) ? -1 : 1; + break; + + case Line::CA1: +// LOG("LSTRB Motor"); + set_motor_on(!(control_state_ & Line::CA2)); + break; + + case Line::CA0: +// LOG("LSTRB Step"); + step(Storage::Disk::HeadPosition(step_direction_)); + break; + + case Line::CA1 | Line::CA0: +// LOG("LSTRB Eject disk"); + set_disk(nullptr); + break; + } + } } bool DoubleDensityDrive::read() { - return false; + switch(control_state_ & (CA2 | CA1 | CA0 | SEL)) { + default: +// LOG("unknown)"); + return false; + + // Possible other meanings: + // B = ready (0 = ready) + // + // {CA1,CA0,SEL,CA2} + + case 0: // Head step direction. + // (0 = inward) +// LOG("head step direction)"); + return step_direction_ <= 0; + + case SEL: // Disk in place. + // (0 = disk present) +// LOG("disk in place)"); + return !has_disk(); + + case CA0: // Disk head step completed. + // (0 = still stepping) +// LOG("head stepping)"); + return true; + + case CA0|SEL: // Disk locked. + // (0 = write protected) +// LOG("disk locked)"); + return !get_is_read_only(); + + case CA1: // Disk motor running. + // (0 = motor on) +// LOG("disk motor running)"); + return !get_motor_on(); + + case CA1|SEL: // Head at track 0. + // (0 = at track 0) +// LOG("head at track 0)"); + return !get_is_track_zero(); + + case CA1|CA0|SEL: // Tachometer. + // (arbitrary) + return get_tachometer(); + + case CA2: // Read data, lower head. +// LOG("data, lower head)\n"); + set_head(0); + return false;; + + case CA2|SEL: // Read data, upper head. +// LOG("data, upper head)\n"); + set_head(1); + return false; + + case CA2|CA1: // Single- or double-sided drive. + // (0 = single sided) +// LOG("single- or double-sided drive)"); + return get_head_count() != 1; + + case CA2|CA1|CA0: // "Present/HD" (per the Mac Plus ROM) + // (0 = ??HD??) +// LOG("present/HD)"); + return false; + + case CA2|CA1|CA0|SEL: // Drive installed. + // (0 = present, 1 = missing) +// LOG("drive installed)"); + return false; + } } void DoubleDensityDrive::write(bool value) { diff --git a/Components/DiskII/MacintoshDoubleDensityDrive.hpp b/Components/DiskII/MacintoshDoubleDensityDrive.hpp index cc4f7f1cb..7e070b7db 100644 --- a/Components/DiskII/MacintoshDoubleDensityDrive.hpp +++ b/Components/DiskII/MacintoshDoubleDensityDrive.hpp @@ -28,6 +28,8 @@ class DoubleDensityDrive: public IWMDrive { void did_step(Storage::Disk::HeadPosition to_position) override; bool is_800k_; + int control_state_; + int step_direction_; }; }