mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-02 16:38:51 +00:00
Adds the CNT input.
This commit is contained in:
parent
738999a8b7
commit
b4ec9d70da
@ -60,6 +60,9 @@ template <typename PortHandlerT, Personality personality> class MOS6526:
|
||||
/// @returns @c true if the interrupt output is active, @c false otherwise.
|
||||
bool get_interrupt_line();
|
||||
|
||||
/// Sets the current state of the CNT input.
|
||||
void set_cnt_input(bool active);
|
||||
|
||||
private:
|
||||
PortHandlerT &port_handler_;
|
||||
TODStorage<personality == Personality::P8250> tod_;
|
||||
|
@ -48,6 +48,12 @@ bool MOS6526<BusHandlerT, personality>::get_interrupt_line() {
|
||||
return interrupt_state_ & 0x80;
|
||||
}
|
||||
|
||||
template <typename BusHandlerT, Personality personality>
|
||||
void MOS6526<BusHandlerT, personality>::set_cnt_input(bool active) {
|
||||
cnt_edge_ = active && !cnt_state_;
|
||||
cnt_state_ = active;
|
||||
}
|
||||
|
||||
template <typename BusHandlerT, Personality personality>
|
||||
void MOS6526<BusHandlerT, personality>::write(int address, uint8_t value) {
|
||||
address &= 0xf;
|
||||
@ -166,11 +172,13 @@ void MOS6526<BusHandlerT, personality>::run_for(const HalfCycles half_cycles) {
|
||||
pending_ &= PendingClearMask;
|
||||
|
||||
// TODO: use CNT potentially to clock timer A, elimiante conditional above.
|
||||
const bool timer1_did_reload = counter_[0].template advance<false>(false);
|
||||
const bool timer1_did_reload = counter_[0].template advance<false>(false, cnt_state_, cnt_edge_);
|
||||
|
||||
const bool timer1_carry = timer1_did_reload && (counter_[1].control & 0x60) == 0x40;
|
||||
const bool timer2_did_reload = counter_[1].template advance<true>(timer1_carry);
|
||||
const bool timer2_did_reload = counter_[1].template advance<true>(timer1_carry, cnt_state_, cnt_edge_);
|
||||
posit_interrupt((timer1_did_reload ? 0x01 : 0x00) | (timer2_did_reload ? 0x02 : 0x00));
|
||||
|
||||
cnt_edge_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,6 +174,8 @@ template <> class TODStorage<true>: public TODBase {
|
||||
};
|
||||
|
||||
struct MOS6526Storage {
|
||||
bool cnt_state_ = false; // Inactive by default.
|
||||
bool cnt_edge_ = false;
|
||||
HalfCycles half_divider_;
|
||||
|
||||
uint8_t output_[2] = {0, 0};
|
||||
@ -206,7 +208,7 @@ struct MOS6526Storage {
|
||||
control = v;
|
||||
}
|
||||
|
||||
template <bool is_counter_2> bool advance(bool chained_input) {
|
||||
template <bool is_counter_2> bool advance(bool chained_input, bool cnt_state, bool cnt_edge) {
|
||||
// TODO: remove most of the conditionals here in favour of bit shuffling.
|
||||
|
||||
pending = (pending & PendingClearMask) << 1;
|
||||
@ -222,27 +224,31 @@ struct MOS6526Storage {
|
||||
control &= ~0x10;
|
||||
}
|
||||
|
||||
// Keep a history of the one-shot bit.
|
||||
if(control & 0x08) {
|
||||
pending |= OneShotInOne;
|
||||
}
|
||||
|
||||
// Determine whether an input clock is applicable.
|
||||
if constexpr(is_counter_2) {
|
||||
switch(control&0x60) {
|
||||
case 0x00: // Count Phi2 pulses.
|
||||
pending |= TestInputNow;
|
||||
break;
|
||||
case 0x20: // Count negative CNTs, with an extra cycle of delay.
|
||||
pending |= cnt_edge ? TestInputInOne : 0;
|
||||
break;
|
||||
case 0x40: // Count timer A reloads.
|
||||
pending |= chained_input ? TestInputNow : 0;
|
||||
break;
|
||||
|
||||
case 0x20: // Count negative CNTs.
|
||||
case 0x60: // Count timer A transitions when CNT is low.
|
||||
default:
|
||||
// TODO: all other forms of input.
|
||||
assert(false);
|
||||
pending |= chained_input && cnt_edge ? TestInputNow : 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(!(control&0x20)) {
|
||||
pending |= TestInputNow;
|
||||
} else if (chained_input) { // TODO: check CNT directly, probably?
|
||||
} else if (cnt_edge) {
|
||||
pending |= TestInputInOne;
|
||||
}
|
||||
}
|
||||
@ -250,11 +256,6 @@ struct MOS6526Storage {
|
||||
pending |= ApplyClockInTwo;
|
||||
}
|
||||
|
||||
// Keep a history of the one-shot bit.
|
||||
if(control & 0x08) {
|
||||
pending |= OneShotInOne | OneShotNow;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Perform a timer tick and decide whether a reload is prompted.
|
||||
|
@ -288,7 +288,6 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineTrapHandler {
|
||||
}
|
||||
|
||||
func testCIALoadTH() {
|
||||
// TODO: Uses one of the CNT input modes of timer B.
|
||||
runTest("loadth", suffixes: [""], processor: .processor6502)
|
||||
}
|
||||
|
||||
@ -313,7 +312,6 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachineTrapHandler {
|
||||
}
|
||||
|
||||
func testCIACNTDefault() {
|
||||
// TODO: Uses one of the CNT input modes of timer B.
|
||||
runTest("cntdef", suffixes: [""], processor: .processor6502)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user