1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-26 15:32:04 +00:00

Fixed 'same value, then immediate increment, then proper counting increments' behaviour and ensured it takes one cycle to commit a value. Adjusted tests to match.

This commit is contained in:
Thomas Harte 2017-03-04 15:57:54 -05:00
parent 837cccdf83
commit e09b76bf32
2 changed files with 56 additions and 22 deletions

View File

@ -51,7 +51,7 @@ template <class T> class MOS6532 {
if(address & 0x10)
{
timer_.writtenShift = timer_.activeShift = (decodedAddress - 0x04) * 3 + (decodedAddress / 0x07); // i.e. 0, 3, 6, 10
timer_.value = ((unsigned int)(value) << timer_.activeShift) | ((1 << timer_.activeShift)-1);
timer_.value = ((unsigned int)value << timer_.activeShift) + 2;
timer_.interrupt_enabled = !!(address&0x08);
interrupt_status_ &= ~InterruptFlag::Timer;
evaluate_interrupts();

View File

@ -21,14 +21,29 @@ class MOS6532Tests: XCTestCase {
with6532 {
// set a count of 128 at single-clock intervals
$0.setValue(128, forRegister:0x14)
// run for one clock and the count should now be 127
$0.run(forCycles: 1)
XCTAssert($0.value(forRegister: 4) == 127, "A single tick should decrease the counter once")
// run for a further 200 clock counts; timer should reach -73 = 183
$0.run(forCycles: 200)
XCTAssert($0.value(forRegister: 4) == 183, "Timer should underflow and keep counting")
// one cycle later the timer should still contain 128
$0.run(forCycles: 1)
XCTAssertEqual($0.value(forRegister: 4), 128)
// run for one more clock and the count should now be 127
$0.run(forCycles: 1)
XCTAssertEqual($0.value(forRegister: 4), 127)
// run for 127 clocks and the timer should be zero, but the timer flag will not yet be set
$0.run(forCycles: 127)
XCTAssertEqual($0.value(forRegister: 5) & 0x80, 0)
XCTAssertEqual($0.value(forRegister: 4), 0)
// after one more cycle the counter should be 255 and the timer flag will now be set
$0.run(forCycles: 1)
XCTAssertEqual($0.value(forRegister: 5) & 0x80, 0x80)
XCTAssertEqual($0.value(forRegister: 4), 255)
// run for a further 55 clock counts; timer should reach -200
$0.run(forCycles: 55)
XCTAssertEqual($0.value(forRegister: 4), 200)
}
}
@ -37,26 +52,44 @@ class MOS6532Tests: XCTestCase {
with6532 {
// set a count of 28 at eight-clock intervals
$0.setValue(28, forRegister:0x15)
// run for seven clock and the count should still be 28
$0.run(forCycles: 7)
XCTAssert($0.value(forRegister: 4) == 28, "The timer should remain unchanged for seven clocks")
// run for a further clock and the count should now be 27
$0.run(forCycles: 1)
XCTAssert($0.value(forRegister: 4) == 27, "The timer should have decremented once after 8 cycles")
// run for a further 7 + 27*8 + 5 = 228 clock counts; timer should reach -5 = 0xfb
$0.run(forCycles: 228)
XCTAssert($0.value(forRegister: 4) == 0xfb, "Timer should underflow and start counting at single-clock pace")
// one cycle later the timer should still contain 28
$0.run(forCycles: 1)
XCTAssertEqual($0.value(forRegister: 4), 28)
// one further cycle and the timer should hit 27
$0.run(forCycles: 1)
XCTAssertEqual($0.value(forRegister: 4), 27)
// run for seven clock and the count should still be 27
$0.run(forCycles: 7)
XCTAssertEqual($0.value(forRegister: 4), 27)
// run for a further clock and the count should now be 26
$0.run(forCycles: 1)
XCTAssertEqual($0.value(forRegister: 4), 26)
// run for another 26 * 8 = 208 cycles and the count should hit zero without setting the timer flag, and
// stay there for seven more cycles
$0.run(forCycles: 208)
for _ in 0 ..< 8 {
XCTAssertEqual($0.value(forRegister: 5) & 0x80, 0)
XCTAssertEqual($0.value(forRegister: 4), 0)
$0.run(forCycles: 1)
}
// run six more, and the timer should reach 249, with the interrupt flag set
$0.run(forCycles: 6)
XCTAssertEqual($0.value(forRegister: 5) & 0x80, 0x80)
XCTAssertEqual($0.value(forRegister: 4), 249)
// timer should now resume dividing by eight
$0.run(forCycles: 7)
XCTAssert($0.value(forRegister: 4) == 0xfb, "Timer should remain unchanged for seven cycles")
XCTAssertEqual($0.value(forRegister: 4), 249)
// timer should now resume dividing by eight
$0.run(forCycles: 1)
XCTAssert($0.value(forRegister: 4) == 0xfa, "Timer should decrement after eighth cycle")
XCTAssertEqual($0.value(forRegister: 4), 248)
}
}
@ -64,10 +97,11 @@ class MOS6532Tests: XCTestCase {
with6532 {
// set a count of 1 at single-clock intervals
$0.setValue(1, forRegister:0x1c)
// run for one clock and the count should now be zero
$0.run(forCycles: 1)
// run for two clocks and the count should now be zero
$0.run(forCycles: 2)
// interrupt shouldn't be signalled yet, bit should not be set
XCTAssert(!$0.irqLine, "IRQ line should not be set")
XCTAssert($0.value(forRegister: 5) == 0x00, "Counter interrupt should not be set")