From b93575bbcc0513814246590e121954fcea4904a9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 27 Jun 2021 22:33:20 -0400 Subject: [PATCH] Spots that b0 and b2 of 0xb4 are 'dividers', not enables. --- Machines/Enterprise/Dave.cpp | 15 ++++++++++++--- Machines/Enterprise/Dave.hpp | 6 +++++- Machines/Enterprise/Enterprise.cpp | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Machines/Enterprise/Dave.cpp b/Machines/Enterprise/Dave.cpp index 513f0fcbc..7a1bec51e 100644 --- a/Machines/Enterprise/Dave.cpp +++ b/Machines/Enterprise/Dave.cpp @@ -234,11 +234,14 @@ void TimedInterruptSource::run_for(Cycles cycles) { // Update the programmable-frequency interrupt. programmable_offset_ -= cycles.as(); if(programmable_offset_ < 0) { - interrupts_ |= uint8_t(Interrupt::VariableFrequency); + if(programmable_level_) { + interrupts_ |= uint8_t(Interrupt::VariableFrequency); + } + programmable_level_ ^= true; switch(rate_) { - case InterruptRate::OnekHz: programmable_offset_ = 249; break; - case InterruptRate::FiftyHz: programmable_offset_ = 4999; break; + case InterruptRate::OnekHz: programmable_offset_ = 124; break; + case InterruptRate::FiftyHz: programmable_offset_ = 2499; break; case InterruptRate::ToneGenerator0: programmable_offset_ = channels_[0].value; break; case InterruptRate::ToneGenerator1: programmable_offset_ = channels_[1].value; break; } @@ -250,3 +253,9 @@ Cycles TimedInterruptSource::get_next_sequence_point() const { // generate activity when it underflows, not when it hits zero. return (programmable_offset_+1) < one_hz_offset_.as() ? Cycles(programmable_offset_+1) : one_hz_offset_; } + +uint8_t TimedInterruptSource::get_divider_state() { + return + (one_hz_offset_ < half_clock_rate ? 0x4 : 0x0) | + (programmable_level_ ? 0x1 : 0x0); +} diff --git a/Machines/Enterprise/Dave.hpp b/Machines/Enterprise/Dave.hpp index f9fa19116..c2a0873d5 100644 --- a/Machines/Enterprise/Dave.hpp +++ b/Machines/Enterprise/Dave.hpp @@ -122,6 +122,7 @@ class TimedInterruptSource { void write(uint16_t address, uint8_t value); uint8_t get_new_interrupts(); + uint8_t get_divider_state(); void run_for(Cycles); @@ -131,9 +132,12 @@ class TimedInterruptSource { uint8_t interrupts_ = 0; static constexpr Cycles clock_rate{250000}; + static constexpr Cycles half_clock_rate{125000}; Cycles one_hz_offset_ = clock_rate; - uint16_t programmable_offset_ = 0; + + int programmable_offset_ = 0; + bool programmable_level_ = false; enum class InterruptRate { OnekHz, diff --git a/Machines/Enterprise/Enterprise.cpp b/Machines/Enterprise/Enterprise.cpp index 48019ec10..87ecbe20a 100644 --- a/Machines/Enterprise/Enterprise.cpp +++ b/Machines/Enterprise/Enterprise.cpp @@ -342,7 +342,7 @@ template class ConcreteMachine: case 0xb3: *cycle.value = pages_[3]; break; case 0xb4: - *cycle.value = interrupt_mask_ | interrupt_state_; + *cycle.value = (interrupt_mask_ & 0xf0) | dave_timer_->get_divider_state() | interrupt_state_; break; case 0xb5: if(active_key_line_ < key_lines_.size()) {