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:
@@ -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));
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user