From ad16db1e84ee22ce794e9dd4ee60dfaabca248e2 Mon Sep 17 00:00:00 2001 From: Uri Shaked Date: Wed, 29 Apr 2020 23:07:27 +0300 Subject: fix(timer): Reading TCNT in 2-cycle instructions close #40 --- src/peripherals/timer.spec.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src/peripherals/timer.spec.ts') diff --git a/src/peripherals/timer.spec.ts b/src/peripherals/timer.spec.ts index 7d280ed..8733f73 100644 --- a/src/peripherals/timer.spec.ts +++ b/src/peripherals/timer.spec.ts @@ -95,7 +95,7 @@ describe('timer', () => { cpu.cycles = 1; timer.tick(); const tcnt = cpu.readData(0x46); - expect(tcnt).toEqual(0); // TCNT should be 0 + expect(tcnt).toEqual(2); // TCNT should be 2 (one tick above + 2 cycles for interrupt) expect(cpu.data[0x35]).toEqual(0); // TOV bit in TIFR should be clear expect(cpu.pc).toEqual(0x20); expect(cpu.cycles).toEqual(3); @@ -183,7 +183,7 @@ describe('timer', () => { cpu.cycles = 1; timer.tick(); const tcnt = cpu.readData(0x46); - expect(tcnt).toEqual(0x21); // TCNT should be 0x21 + expect(tcnt).toEqual(0x23); // TCNT should be 0x23 (one tick above + 2 cycles for interrupt) expect(cpu.data[0x35]).toEqual(0); // OCFA bit in TIFR should be clear expect(cpu.pc).toEqual(0x1c); expect(cpu.cycles).toEqual(3); @@ -216,7 +216,7 @@ describe('timer', () => { cpu.cycles = 1; timer.tick(); const tcnt = cpu.readData(0x46); - expect(tcnt).toEqual(0x21); // TCNT should be 0x21 + expect(tcnt).toEqual(0x23); // TCNT should be 0x23 (one tick above + 2 cycles for interrupt) expect(cpu.data[0x35]).toEqual(0); // OCFB bit in TIFR should be clear expect(cpu.pc).toEqual(0x1e); expect(cpu.cycles).toEqual(3); @@ -255,6 +255,24 @@ describe('timer', () => { expect(cpu.readData(0xb2)).toEqual(2); // TCNT2 should be 2 }); + it('should update TCNT as it is being read by a 2-cycle instruction (issue #40)', () => { + const program = [ + 'LDI r16, 0x1', // TCCR0B = 1 << CS00; + 'OUT 0x25, r16', + 'LDI r16, 0x0', // TCNT0 <- 0x30 + 'OUT 0x26, r16', + 'NOP', + 'LDS r1, 0x46', // r17 <- TCNT0 (2 cycles) + ]; + loadProgram(...program); + const timer = new AVRTimer(cpu, timer0Config); + for (let i = 0; i < program.length; i++) { + avrInstruction(cpu); + timer.tick(); + } + expect(cpu.data[1]).toEqual(2); // r1 should equal 2 + }); + describe('16 bit timers', () => { it('should increment 16-bit TCNT by 1', () => { const timer = new AVRTimer(cpu, timer1Config); @@ -301,7 +319,7 @@ describe('timer', () => { cpu.cycles = 1; timer.tick(); cpu.readData(0x84); // Refresh TCNT1 - expect(cpu.dataView.getUint16(0x84, true)).toEqual(0); // TCNT1 should be 0 + expect(cpu.dataView.getUint16(0x84, true)).toEqual(2); // TCNT1 should be 0 (one tick above + 2 cycles for interrupt) expect(cpu.data[0x36]).toEqual(0); // TOV bit in TIFR should be clear expect(cpu.pc).toEqual(0x1a); expect(cpu.cycles).toEqual(3); -- cgit v1.2.3