From d53d1c616fa74c9c314820eb1a76329955360a4a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 12 Jul 2019 21:20:05 -0400 Subject: [PATCH] Continues trying to get to write support. --- Components/DiskII/IWM.cpp | 85 ++++++++++++++++++++++++++++++++++----- Components/DiskII/IWM.hpp | 11 +++++ 2 files changed, 87 insertions(+), 9 deletions(-) diff --git a/Components/DiskII/IWM.cpp b/Components/DiskII/IWM.cpp index 1ab0bfefc..a1e1cd7d9 100644 --- a/Components/DiskII/IWM.cpp +++ b/Components/DiskII/IWM.cpp @@ -86,7 +86,7 @@ uint8_t IWM::read(int address) { return uint8_t( (mode_&0x1f) | ((state_ & ENABLE) ? 0x20 : 0x00) | - (drives_[active_drive_] ? (drives_[active_drive_]->read() ? 0x80 : 0x00) : 0x80) + sense() ); } break; @@ -138,6 +138,14 @@ void IWM::write(int address, uint8_t input) { case Q7|Q6|ENABLE: // Write data register. LOG("Data register write"); + +// if(write_handshake_ & 0x80) { +// shift_register_ = input; +// output_bits_remaining_ = 8; +// } else { +// next_output_ = input; +// write_handshake_ &= ~0x80; +// } break; } } @@ -158,7 +166,7 @@ void IWM::access(int address) { state_ &= ~mask; } - // React appropriately to motor requests and to LSTRB register writes. + // React appropriately to ENABLE and DRIVESEL changes, and changes into/out of write mode. if(old_state != state_) { push_drive_state(); @@ -189,6 +197,34 @@ void IWM::access(int address) { } } } break; + + case Q6: + case Q7: { + const auto old_shift_mode = shift_mode_; + + switch(state_ & (Q6|Q7)) { + default: shift_mode_ = ShiftMode::CheckingWriteProtect; break; + case 0: shift_mode_ = ShiftMode::Reading; break; + case Q7: + // "The IWM is put into the write state by a transition from the write protect sense state to the + // write load state". + if(shift_mode_ == ShiftMode::CheckingWriteProtect) shift_mode_ = ShiftMode::Writing; + break; + } + +// LOG("Shift mode is now " << int(shift_mode_)); + + if(drives_[active_drive_]) { + if(old_shift_mode == ShiftMode::Writing && shift_mode_ != ShiftMode::Writing) { + drives_[active_drive_]->end_writing(); + write_handshake_ = 0xc0; + } + + if(old_shift_mode != ShiftMode::Writing && shift_mode_ == ShiftMode::Writing) { + drives_[active_drive_]->begin_writing(Storage::Time(1, clock_rate_), false); + } + } + } break; } } } @@ -227,9 +263,8 @@ void IWM::run_for(const Cycles cycles) { // Activity otherwise depends on mode and motor state. int integer_cycles = cycles.as_int(); - switch(state_ & (Q6 | Q7 | ENABLE)) { - case 0: - case ENABLE: // i.e. read mode. + switch(shift_mode_) { + case ShiftMode::Reading: if(drive_is_rotating_[active_drive_]) { while(integer_cycles--) { drives_[active_drive_]->run_for(Cycles(1)); @@ -247,10 +282,38 @@ void IWM::run_for(const Cycles cycles) { } break; - case Q6|Q7: - case Q6|Q7|ENABLE: // write mode? - printf("IWM write mode?\n"); - break; +/* case ShiftMode::Writing: + while(cycles_since_shift_ + integer_cycles >= bit_length_) { + const auto cycles_until_write = cycles_since_shift_ + integer_cycles - bit_length_; + drives_[active_drive_]->run_for(cycles_until_write); + + drives_[active_drive_]->write_bit(shift_register_ & 0x80); // Is this correct? + shift_register_ <<= 1; + cycles_since_shift_ = Cycles(0); + + integer_cycles -= cycles_until_write.as_int(); + --output_bits_remaining_; + + if(!output_bits_remaining_) { + if(!(write_handshake_ & 0x80)) { + write_handshake_ |= 0x80; + shift_register_ = next_output_; + output_bits_remaining_ = 8; + } else { + write_handshake_ &= ~0x40; + drives_[active_drive_]->end_writing(); + } + } + } + + cycles_since_shift_ = integer_cycles; + break;*/ + +// case ShiftMode::CheckingWriteProtect: +// while(--integer_cycles) { +// shift_register_ = (shift_register_ >> 1) | sense(); +// } +// break; default: if(drive_is_rotating_[active_drive_]) drives_[active_drive_]->run_for(cycles); @@ -258,6 +321,10 @@ void IWM::run_for(const Cycles cycles) { } } +uint8_t IWM::sense() { + return drives_[active_drive_] ? (drives_[active_drive_]->read() ? 0x80 : 0x00) : 0x80; +} + void IWM::process_event(const Storage::Disk::Drive::Event &event) { switch(event.type) { case Storage::Disk::Track::Event::IndexHole: return; diff --git a/Components/DiskII/IWM.hpp b/Components/DiskII/IWM.hpp index 103ed79e5..6c7801316 100644 --- a/Components/DiskII/IWM.hpp +++ b/Components/DiskII/IWM.hpp @@ -92,11 +92,22 @@ class IWM: void access(int address); uint8_t shift_register_ = 0; + uint8_t next_output_ = 0; + int output_bits_remaining_ = 0; + void propose_shift(uint8_t bit); Cycles cycles_since_shift_; Cycles bit_length_; void push_drive_state(); + + enum class ShiftMode { + Reading, + Writing, + CheckingWriteProtect + } shift_mode_; + + uint8_t sense(); };