diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 816f7ce8d..b0edbd770 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -144,30 +144,38 @@ template class MOS6522 { { } - void run_for_cycles(unsigned int number_of_cycles) + void run_for_half_cycles(unsigned int number_of_cycles) { - _registers.timer[0] -= number_of_cycles; - _registers.timer[1] -= number_of_cycles; - - if(!_registers.timer[1] && _timer_is_running[1]) + while(number_of_cycles--) { - _timer_is_running[1] = false; - _registers.interrupt_flags |= InterruptFlag::Timer2; - reevaluate_interrupts(); - } + if(_is_phase2) + { + _registers.timer[0] --; + _registers.timer[1] --; - if(!_registers.timer[0] && _timer_is_running[0]) - { - _registers.interrupt_flags |= InterruptFlag::Timer1; - reevaluate_interrupts(); + if(!_registers.timer[1] && _timer_is_running[1]) + { + _timer_is_running[1] = false; + _registers.interrupt_flags |= InterruptFlag::Timer2; + reevaluate_interrupts(); + } - // TODO: reload shouldn't occur for a further 1.5 cycles - if(_registers.auxiliary_control&0x40) - _registers.timer[0] = _registers.timer_latch[0]; - else - _timer_is_running[0] = false; + if(!_registers.timer[0] && _timer_is_running[0]) + { + _registers.interrupt_flags |= InterruptFlag::Timer1; + reevaluate_interrupts(); + + // TODO: reload shouldn't occur for a further 1.5 cycles + if(_registers.auxiliary_control&0x40) + _registers.timer[0] = _registers.timer_latch[0]; + else + _timer_is_running[0] = false; + } + // TODO: lots of other status effects + } + + _is_phase2 ^= true; } - // TODO: lots of other status effects } bool get_interrupt_line() @@ -178,13 +186,18 @@ template class MOS6522 { MOS6522() : _timer_is_running{false, false}, - _last_posted_interrupt_status(false) + _last_posted_interrupt_status(false), + _is_phase2(false) {} private: - // Intended to be overwritten + // Intended to be overridden uint8_t get_port_input(int port) { return 0xff; } void set_port_output(int port, uint8_t value) {} +// void set_interrupt_status(bool status) {} + + // Phase toggle + bool _is_phase2; // Delegate and communications bool _last_posted_interrupt_status; diff --git a/Machines/Vic-20/Vic20.cpp b/Machines/Vic-20/Vic20.cpp index 5a60dcc1d..71888551f 100644 --- a/Machines/Vic-20/Vic20.cpp +++ b/Machines/Vic-20/Vic20.cpp @@ -79,8 +79,8 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin } } - _userPortVIA.run_for_cycles(1); - _keyboardVIA.run_for_cycles(1); + _userPortVIA.run_for_half_cycles(2); + _keyboardVIA.run_for_half_cycles(2); return 1; } diff --git a/OSBindings/Mac/Clock SignalTests/6522Tests.swift b/OSBindings/Mac/Clock SignalTests/6522Tests.swift index 833d17621..567337c4a 100644 --- a/OSBindings/Mac/Clock SignalTests/6522Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/6522Tests.swift @@ -10,4 +10,21 @@ import XCTest import Foundation class MOS6522Tests: XCTestCase { + + private func with6522(action: (MOS6522Bridge) -> ()) { + let bridge = MOS6522Bridge() + action(bridge) + } + + func testTimerCount() { + with6522 { + $0.setValue(10, forRegister: 4) + $0.setValue(0, forRegister: 5) + + $0.runForHalfCycles(10) + + XCTAssert($0.valueForRegister(4) == 5, "Low order byte of timer should be 5; was \($0.valueForRegister(4))") + XCTAssert($0.valueForRegister(5) == 0, "High order byte of timer should be 5; was \($0.valueForRegister(5))") + } + } } diff --git a/OSBindings/Mac/Clock SignalTests/MOS6522Bridge.mm b/OSBindings/Mac/Clock SignalTests/MOS6522Bridge.mm index 0f1a725ed..329dbb06a 100644 --- a/OSBindings/Mac/Clock SignalTests/MOS6522Bridge.mm +++ b/OSBindings/Mac/Clock SignalTests/MOS6522Bridge.mm @@ -49,7 +49,7 @@ class VanillaVIA: public MOS::MOS6522 { - (void)runForHalfCycles:(NSUInteger)numberOfHalfCycles { - _via.run_for_cycles(numberOfHalfCycles); + _via.run_for_half_cycles(numberOfHalfCycles); } @end