1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-08-17 07:29:04 +00:00
CLK/Components/6526/Implementation/6526Storage.hpp

86 lines
1.5 KiB
C++
Raw Normal View History

//
// 6526Storage.hpp
// Clock Signal
//
// Created by Thomas Harte on 18/07/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef _526Storage_h
#define _526Storage_h
namespace MOS {
namespace MOS6526 {
struct MOS6526Storage {
HalfCycles half_divider_;
uint8_t output_[2] = {0, 0};
uint8_t data_direction_[2] = {0, 0};
2021-07-24 01:58:52 +00:00
uint8_t interrupt_control_ = 0;
2021-07-24 01:58:52 +00:00
uint8_t interrupt_state_ = 0;
uint32_t tod_increment_mask_ = uint32_t(~0);
uint32_t tod_latch_ = 0;
uint32_t tod_ = 0;
uint32_t tod_alarm_ = 0;
struct Counter {
uint16_t reload = 0;
uint16_t value = 0;
2021-07-24 02:43:47 +00:00
uint8_t control = 0;
2021-07-24 19:53:18 +00:00
bool is_counting = false;
2021-07-24 02:43:47 +00:00
template <int shift> void set_reload(uint8_t v) {
reload = (reload & (0xff00 >> shift)) | uint16_t(v << shift);
if constexpr (shift == 8) {
if(!is_counting) {
is_counting = true;
value = reload;
}
}
}
template <bool is_counter_2> void set_control(uint8_t v) {
control = v & 0xef;
if(v & 0x10) {
value = reload;
}
is_counting |= (v & 0x18) == 0x10;
}
2021-07-24 02:43:47 +00:00
int subtract(int count) {
if(control & 8) {
// One-shot.
2021-07-24 19:53:18 +00:00
if(is_counting) {
if(value < count) {
value = reload;
is_counting = false;
return 1;
} else {
value -= count;
}
}
2021-07-24 02:43:47 +00:00
return 0;
} else {
// Continuous.
value -= count;
value -= (reload + 1);
const int underflows = -value / (reload + 1);
value %= (reload + 1);
value += (reload + 1);
return underflows;
}
}
} counter_[2];
};
}
}
#endif /* _526Storage_h */