1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-09 05:25:01 +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> template <typename BusHandlerT, Personality personality>
void MOS6526<BusHandlerT, personality>::posit_interrupt(uint8_t mask) { void MOS6526<BusHandlerT, personality>::posit_interrupt(uint8_t mask) {
if(!mask) {
return;
}
interrupt_state_ |= mask; interrupt_state_ |= mask;
update_interrupts(); update_interrupts();
} }
@@ -36,7 +39,7 @@ void MOS6526<BusHandlerT, personality>::posit_interrupt(uint8_t mask) {
template <typename BusHandlerT, Personality personality> template <typename BusHandlerT, Personality personality>
void MOS6526<BusHandlerT, personality>::update_interrupts() { void MOS6526<BusHandlerT, personality>::update_interrupts() {
if(interrupt_state_ & interrupt_control_) { 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>(); int sub = half_divider_.divide_cycles().template as<int>();
while(sub--) { 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_[0].advance(false);
counter_[1].advance(counter_[0].hit_zero); counter_[1].advance(counter_[0].hit_zero);
posit_interrupt((counter_[0].hit_zero ? 0x01 : 0x00) | (counter_[1].hit_zero ? 0x02 : 0x00)); 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) { template <int shift> void set_reload(uint8_t v) {
reload = (reload & (0xff00 >> shift)) | uint16_t(v << shift); reload = (reload & (0xff00 >> shift)) | uint16_t(v << shift);
// if constexpr (shift == 8) { if constexpr (shift == 8) {
// if(!(control&1)) { if(!(control&1)) {
// value = reload; pending |= ReloadInOne;
// } }
// } }
} }
template <bool is_counter_2> void set_control(uint8_t v) { template <bool is_counter_2> void set_control(uint8_t v) {
control = v & 0xef; control = v;
if(v & 0x10) {
pending |= ReloadInTwo;
}
} }
void advance(bool chained_input) { void advance(bool chained_input) {
@@ -54,8 +51,9 @@ struct MOS6526Storage {
pending <<= 1; pending <<= 1;
if(hit_zero && pending&(OneShotInOne | OneShotNow)) { if(control & 0x10) {
control &= ~1; pending |= ReloadInTwo;
control &= ~0x10;
} }
if((control & 0x01) || chained_input) { if((control & 0x01) || chained_input) {
@@ -67,7 +65,7 @@ struct MOS6526Storage {
if((pending & ReloadNow) || (hit_zero && (pending & ApplyClockInTwo))) { if((pending & ReloadNow) || (hit_zero && (pending & ApplyClockInTwo))) {
value = reload; value = reload;
pending &= ~ApplyClockInTwo; pending &= ~ApplyClockInOne;
} }
pending &= PendingClearMask; pending &= PendingClearMask;
@@ -78,6 +76,10 @@ struct MOS6526Storage {
} else { } else {
hit_zero = false; hit_zero = false;
} }
if(hit_zero && pending&(OneShotInOne | OneShotNow)) {
control &= ~1;
}
} }
private: private:
@@ -96,10 +98,15 @@ struct MOS6526Storage {
static constexpr int ApplyClockInOne = 1 << 8; static constexpr int ApplyClockInOne = 1 << 8;
static constexpr int ApplyClockNow = 1 << 9; static constexpr int ApplyClockNow = 1 << 9;
static constexpr int PendingClearMask = ~(ReloadNow | OneShotNow); static constexpr int PendingClearMask = ~(ReloadNow | OneShotNow | ApplyClockNow);
bool active_ = false; bool active_ = false;
} counter_[2]; } counter_[2];
static constexpr int InterruptInOne = 1 << 0;
static constexpr int InterruptNow = 1 << 1;
static constexpr int PendingClearMask = ~(InterruptNow);
int pending_ = 0;
}; };
} }