mirror of
https://github.com/TomHarte/CLK.git
synced 2025-11-25 20:18:01 +00:00
Correct uPD7002 interrupt wiring.
This commit is contained in:
@@ -24,9 +24,8 @@ void uPD7002::run_for(const HalfCycles count) {
|
|||||||
|
|
||||||
if(count >= conversion_time_remaining_) {
|
if(count >= conversion_time_remaining_) {
|
||||||
conversion_time_remaining_ = HalfCycles(0);
|
conversion_time_remaining_ = HalfCycles(0);
|
||||||
interrupt_ = true;
|
|
||||||
result_ = uint16_t(inputs_[channel_] * 65535.0f) & (high_precision_ ? 0xfff0 : 0xff00);
|
result_ = uint16_t(inputs_[channel_] * 65535.0f) & (high_precision_ ? 0xfff0 : 0xff00);
|
||||||
if(delegate_) delegate_->did_change_interrupt_status(*this);
|
set_interrupt(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,11 +39,11 @@ bool uPD7002::interrupt() const {
|
|||||||
void uPD7002::write(const uint16_t address, const uint8_t value) {
|
void uPD7002::write(const uint16_t address, const uint8_t value) {
|
||||||
const auto local_address = address & 3;
|
const auto local_address = address & 3;
|
||||||
if(!local_address) {
|
if(!local_address) {
|
||||||
interrupt_ = false;
|
|
||||||
channel_ = value & 0b0000'0011;
|
channel_ = value & 0b0000'0011;
|
||||||
spare_ = value & 0b0000'0100;
|
spare_ = value & 0b0000'0100;
|
||||||
high_precision_ = value & 0b0000'1000;
|
high_precision_ = value & 0b0000'1000;
|
||||||
conversion_time_remaining_ = high_precision_ ? slow_period_ : fast_period_;
|
conversion_time_remaining_ = high_precision_ ? slow_period_ : fast_period_;
|
||||||
|
set_interrupt(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,8 +53,7 @@ uint8_t uPD7002::read(const uint16_t address) {
|
|||||||
default:
|
default:
|
||||||
case 0: return status();
|
case 0: return status();
|
||||||
case 1:
|
case 1:
|
||||||
interrupt_ = false;
|
set_interrupt(false);
|
||||||
if(delegate_) delegate_->did_change_interrupt_status(*this);
|
|
||||||
return uint8_t(result_ >> 8);
|
return uint8_t(result_ >> 8);
|
||||||
case 2: return uint8_t(result_);
|
case 2: return uint8_t(result_);
|
||||||
case 3: return 0xff;
|
case 3: return 0xff;
|
||||||
@@ -71,3 +69,13 @@ uint8_t uPD7002::status() const {
|
|||||||
(conversion_time_remaining_ > HalfCycles(0) ? 0x00 : 0x40) |
|
(conversion_time_remaining_ > HalfCycles(0) ? 0x00 : 0x40) |
|
||||||
(interrupt_ ? 0x00 : 0x80);
|
(interrupt_ ? 0x00 : 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uPD7002::set_delegate(Delegate *const delegate) {
|
||||||
|
delegate_ = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uPD7002::set_interrupt(const bool value) {
|
||||||
|
if(interrupt_ == value) return;
|
||||||
|
interrupt_ = value;
|
||||||
|
if(delegate_) delegate_->did_change_interrupt_status(*this);
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ private:
|
|||||||
HalfCycles fast_period_, slow_period_;
|
HalfCycles fast_period_, slow_period_;
|
||||||
|
|
||||||
uint8_t status() const;
|
uint8_t status() const;
|
||||||
|
void set_interrupt(bool);
|
||||||
Delegate *delegate_ = nullptr;
|
Delegate *delegate_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -539,6 +539,7 @@ public:
|
|||||||
|
|
||||||
system_via_port_handler_.set_interrupt_delegate(this);
|
system_via_port_handler_.set_interrupt_delegate(this);
|
||||||
user_via_port_handler_.set_interrupt_delegate(this);
|
user_via_port_handler_.set_interrupt_delegate(this);
|
||||||
|
adc_.set_delegate(this);
|
||||||
|
|
||||||
// Grab ROMs.
|
// Grab ROMs.
|
||||||
using Request = ::ROM::Request;
|
using Request = ::ROM::Request;
|
||||||
@@ -812,7 +813,7 @@ private:
|
|||||||
|
|
||||||
// MARK: - uPD7002::Delegate.
|
// MARK: - uPD7002::Delegate.
|
||||||
void did_change_interrupt_status(NEC::uPD7002 &) override {
|
void did_change_interrupt_status(NEC::uPD7002 &) override {
|
||||||
update_irq_line();
|
system_via_.set_control_line_input<MOS::MOS6522::Port::B, MOS::MOS6522::Line::One>(adc_.interrupt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - MediaTarget.
|
// MARK: - MediaTarget.
|
||||||
@@ -868,8 +869,7 @@ private:
|
|||||||
void update_irq_line() {
|
void update_irq_line() {
|
||||||
m6502_.set_irq_line(
|
m6502_.set_irq_line(
|
||||||
user_via_.get_interrupt_line() ||
|
user_via_.get_interrupt_line() ||
|
||||||
system_via_.get_interrupt_line() /*||
|
system_via_.get_interrupt_line()
|
||||||
adc_.interrupt()*/
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user