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:
parent
116e0f0105
commit
b93575bbcc
@ -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);
|
||||||
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user