1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-27 02:55:07 +00:00

Reintroduces reload-on-off, adds interrupt delay.

This commit is contained in:
Thomas Harte 2021-08-01 21:09:02 -04:00
parent 460a6cb6fe
commit 57dd38aef2
2 changed files with 31 additions and 15 deletions

View File

@ -29,6 +29,9 @@ template <int port> uint8_t MOS6526<BusHandlerT, personality>::get_port_input()
template <typename BusHandlerT, Personality personality>
void MOS6526<BusHandlerT, personality>::posit_interrupt(uint8_t mask) {
if(!mask) {
return;
}
interrupt_state_ |= mask;
update_interrupts();
}
@ -36,7 +39,7 @@ void MOS6526<BusHandlerT, personality>::posit_interrupt(uint8_t mask) {
template <typename BusHandlerT, Personality personality>
void MOS6526<BusHandlerT, personality>::update_interrupts() {
if(interrupt_state_ & interrupt_control_) {
interrupt_state_ |= 0x80;
pending_ |= InterruptInOne;
}
}
@ -237,7 +240,13 @@ void MOS6526<BusHandlerT, personality>::run_for(const HalfCycles half_cycles) {
int sub = half_divider_.divide_cycles().template as<int>();
while(sub--) {
// TODO: use CNT potentially to clock timer A.
pending_ <<= 1;
if(pending_ & InterruptNow) {
interrupt_state_ |= 0x80;
}
pending_ &= PendingClearMask;
// TODO: use CNT potentially to clock timer A, elimiante conditional above.
counter_[0].advance(false);
counter_[1].advance(counter_[0].hit_zero);
posit_interrupt((counter_[0].hit_zero ? 0x01 : 0x00) | (counter_[1].hit_zero ? 0x02 : 0x00));

View File

@ -35,18 +35,15 @@ struct MOS6526Storage {
template <int shift> void set_reload(uint8_t v) {
reload = (reload & (0xff00 >> shift)) | uint16_t(v << shift);
// if constexpr (shift == 8) {
// if(!(control&1)) {
// value = reload;
// }
// }
if constexpr (shift == 8) {
if(!(control&1)) {
pending |= ReloadInOne;
}
}
}
template <bool is_counter_2> void set_control(uint8_t v) {
control = v & 0xef;
if(v & 0x10) {
pending |= ReloadInTwo;
}
control = v;
}
void advance(bool chained_input) {
@ -54,8 +51,9 @@ struct MOS6526Storage {
pending <<= 1;
if(hit_zero && pending&(OneShotInOne | OneShotNow)) {
control &= ~1;
if(control & 0x10) {
pending |= ReloadInTwo;
control &= ~0x10;
}
if((control & 0x01) || chained_input) {
@ -67,7 +65,7 @@ struct MOS6526Storage {
if((pending & ReloadNow) || (hit_zero && (pending & ApplyClockInTwo))) {
value = reload;
pending &= ~ApplyClockInTwo;
pending &= ~ApplyClockInOne;
}
pending &= PendingClearMask;
@ -78,6 +76,10 @@ struct MOS6526Storage {
} else {
hit_zero = false;
}
if(hit_zero && pending&(OneShotInOne | OneShotNow)) {
control &= ~1;
}
}
private:
@ -96,10 +98,15 @@ struct MOS6526Storage {
static constexpr int ApplyClockInOne = 1 << 8;
static constexpr int ApplyClockNow = 1 << 9;
static constexpr int PendingClearMask = ~(ReloadNow | OneShotNow);
static constexpr int PendingClearMask = ~(ReloadNow | OneShotNow | ApplyClockNow);
bool active_ = false;
} counter_[2];
static constexpr int InterruptInOne = 1 << 0;
static constexpr int InterruptNow = 1 << 1;
static constexpr int PendingClearMask = ~(InterruptNow);
int pending_ = 0;
};
}