1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 16:31:42 +00:00

Spots that b0 and b2 of 0xb4 are 'dividers', not enables.

This commit is contained in:
Thomas Harte 2021-06-27 22:33:20 -04:00
parent 116e0f0105
commit b93575bbcc
3 changed files with 18 additions and 5 deletions

View File

@ -234,11 +234,14 @@ void TimedInterruptSource::run_for(Cycles cycles) {
// Update the programmable-frequency interrupt. // Update the programmable-frequency interrupt.
programmable_offset_ -= cycles.as<int>(); programmable_offset_ -= cycles.as<int>();
if(programmable_offset_ < 0) { if(programmable_offset_ < 0) {
interrupts_ |= uint8_t(Interrupt::VariableFrequency); if(programmable_level_) {
interrupts_ |= uint8_t(Interrupt::VariableFrequency);
}
programmable_level_ ^= true;
switch(rate_) { switch(rate_) {
case InterruptRate::OnekHz: programmable_offset_ = 249; break; case InterruptRate::OnekHz: programmable_offset_ = 124; break;
case InterruptRate::FiftyHz: programmable_offset_ = 4999; break; case InterruptRate::FiftyHz: programmable_offset_ = 2499; break;
case InterruptRate::ToneGenerator0: programmable_offset_ = channels_[0].value; break; case InterruptRate::ToneGenerator0: programmable_offset_ = channels_[0].value; break;
case InterruptRate::ToneGenerator1: programmable_offset_ = channels_[1].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. // generate activity when it underflows, not when it hits zero.
return (programmable_offset_+1) < one_hz_offset_.as<int>() ? Cycles(programmable_offset_+1) : one_hz_offset_; return (programmable_offset_+1) < one_hz_offset_.as<int>() ? 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);
}

View File

@ -122,6 +122,7 @@ class TimedInterruptSource {
void write(uint16_t address, uint8_t value); void write(uint16_t address, uint8_t value);
uint8_t get_new_interrupts(); uint8_t get_new_interrupts();
uint8_t get_divider_state();
void run_for(Cycles); void run_for(Cycles);
@ -131,9 +132,12 @@ class TimedInterruptSource {
uint8_t interrupts_ = 0; uint8_t interrupts_ = 0;
static constexpr Cycles clock_rate{250000}; static constexpr Cycles clock_rate{250000};
static constexpr Cycles half_clock_rate{125000};
Cycles one_hz_offset_ = clock_rate; Cycles one_hz_offset_ = clock_rate;
uint16_t programmable_offset_ = 0;
int programmable_offset_ = 0;
bool programmable_level_ = false;
enum class InterruptRate { enum class InterruptRate {
OnekHz, OnekHz,

View File

@ -342,7 +342,7 @@ template <bool has_disk_controller> class ConcreteMachine:
case 0xb3: *cycle.value = pages_[3]; break; case 0xb3: *cycle.value = pages_[3]; break;
case 0xb4: case 0xb4:
*cycle.value = interrupt_mask_ | interrupt_state_; *cycle.value = (interrupt_mask_ & 0xf0) | dave_timer_->get_divider_state() | interrupt_state_;
break; break;
case 0xb5: case 0xb5:
if(active_key_line_ < key_lines_.size()) { if(active_key_line_ < key_lines_.size()) {