From b4ec9d70da01b6e49a3b2e77f8611614be711a92 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 3 Aug 2021 22:19:41 -0400 Subject: [PATCH] Adds the CNT input. --- Components/6526/6526.hpp | 3 +++ .../Implementation/6526Implementation.hpp | 12 +++++++-- .../6526/Implementation/6526Storage.hpp | 25 ++++++++++--------- .../WolfgangLorenzTests.swift | 2 -- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Components/6526/6526.hpp b/Components/6526/6526.hpp index 6d5fc1b5d..3af90d700 100644 --- a/Components/6526/6526.hpp +++ b/Components/6526/6526.hpp @@ -60,6 +60,9 @@ template 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 tod_; diff --git a/Components/6526/Implementation/6526Implementation.hpp b/Components/6526/Implementation/6526Implementation.hpp index bd507f72a..dabdbf353 100644 --- a/Components/6526/Implementation/6526Implementation.hpp +++ b/Components/6526/Implementation/6526Implementation.hpp @@ -48,6 +48,12 @@ bool MOS6526::get_interrupt_line() { return interrupt_state_ & 0x80; } +template +void MOS6526::set_cnt_input(bool active) { + cnt_edge_ = active && !cnt_state_; + cnt_state_ = active; +} + template void MOS6526::write(int address, uint8_t value) { address &= 0xf; @@ -166,11 +172,13 @@ void MOS6526::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); + const bool timer1_did_reload = counter_[0].template advance(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(timer1_carry); + const bool timer2_did_reload = counter_[1].template advance(timer1_carry, cnt_state_, cnt_edge_); posit_interrupt((timer1_did_reload ? 0x01 : 0x00) | (timer2_did_reload ? 0x02 : 0x00)); + + cnt_edge_ = false; } } diff --git a/Components/6526/Implementation/6526Storage.hpp b/Components/6526/Implementation/6526Storage.hpp index c5bd1f08b..4fd369d6d 100644 --- a/Components/6526/Implementation/6526Storage.hpp +++ b/Components/6526/Implementation/6526Storage.hpp @@ -174,6 +174,8 @@ template <> class TODStorage: 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 advance(bool chained_input) { + template 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. diff --git a/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift b/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift index c982e00fc..b89bf83b3 100644 --- a/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift +++ b/OSBindings/Mac/Clock SignalTests/WolfgangLorenzTests.swift @@ -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) }