diff --git a/Machines/Apple/ADB/ReactiveDevice.cpp b/Machines/Apple/ADB/ReactiveDevice.cpp index 67396abf2..b21fe45d4 100644 --- a/Machines/Apple/ADB/ReactiveDevice.cpp +++ b/Machines/Apple/ADB/ReactiveDevice.cpp @@ -10,12 +10,46 @@ using namespace Apple::ADB; -ReactiveDevice::ReactiveDevice(Apple::ADB::Bus &bus) : device_id_(bus.add_device(this)) {} +ReactiveDevice::ReactiveDevice(Apple::ADB::Bus &bus) : bus_(bus), device_id_(bus.add_device(this)) {} void ReactiveDevice::post_response(const std::vector &&response) { response_ = std::move(response); + microseconds_at_bit_ = 0.0; + bit_offset_ = -1; } void ReactiveDevice::advance_state(double microseconds) { - (void)microseconds; + // Do nothing if not in the process of posting a response. + if(response_.empty()) return; + + // Otherwise advance time appropriately. + microseconds_at_bit_ += microseconds; + + // Bit '-1' is the sync signal. + if(bit_offset_ == -1) { + bus_.set_device_output(device_id_, false); + if(microseconds_at_bit_ < 300) { + return; + } + microseconds_at_bit_ -= 300; + ++bit_offset_; + } + + // Advance the implied number of bits. + bit_offset_ += int(microseconds_at_bit_ / 100); + microseconds_at_bit_ -= double(bit_offset_ * 100.0); + + // Check for end-of-transmission. + if(bit_offset_ >= int(response_.size() * 10)) { + bus_.set_device_output(device_id_, true); + response_.clear(); + return; + } + + // Otherwise pick an output level. + const int byte = bit_offset_ / 10; + const int bit = ((0x200 | (int(response_[size_t(byte)]) << 1)) >> (bit_offset_ % 10)) & 1; + + constexpr double low_periods[] = {66, 33}; + bus_.set_device_output(device_id_, microseconds_at_bit_ > low_periods[bit]); } diff --git a/Machines/Apple/ADB/ReactiveDevice.hpp b/Machines/Apple/ADB/ReactiveDevice.hpp index e9c92494d..ab7ade2c6 100644 --- a/Machines/Apple/ADB/ReactiveDevice.hpp +++ b/Machines/Apple/ADB/ReactiveDevice.hpp @@ -25,8 +25,12 @@ class ReactiveDevice: public Bus::Device { void advance_state(double microseconds) override; private: + Bus &bus_; const size_t device_id_; + std::vector response_; + int bit_offset_ = 0; + double microseconds_at_bit_ = 0; }; }