aboutsummaryrefslogtreecommitdiff
path: root/src/peripherals
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/peripherals/timer.spec.ts38
-rw-r--r--src/peripherals/timer.ts9
2 files changed, 26 insertions, 21 deletions
diff --git a/src/peripherals/timer.spec.ts b/src/peripherals/timer.spec.ts
index 1fa0dc6..68f6a66 100644
--- a/src/peripherals/timer.spec.ts
+++ b/src/peripherals/timer.spec.ts
@@ -101,14 +101,20 @@ describe('timer', () => {
expect(tcnt).toEqual(0); // TCNT should stay 0
});
- it('should set the TOV flag when timer reaches the TOP value', () => {
+ it('should set the TOV flag when timer wraps above TOP value', () => {
const cpu = new CPU(new Uint16Array(0x1000));
new AVRTimer(cpu, timer0Config);
cpu.writeData(TCNT0, 0xff);
cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
+
cpu.cycles = 1;
cpu.tick();
expect(cpu.readData(TCNT0)).toEqual(0xff);
+ expect(cpu.data[TIFR0] & TOV0).toEqual(0);
+
+ cpu.cycles++;
+ cpu.tick();
+ expect(cpu.readData(TCNT0)).toEqual(0);
expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0);
});
@@ -294,11 +300,13 @@ describe('timer', () => {
cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
cpu.cycles = 1;
cpu.tick();
- cpu.cycles = 2;
+ cpu.cycles++;
+ cpu.tick();
+ cpu.cycles++;
cpu.tick();
const tcnt = cpu.readData(TCNT0);
- expect(tcnt).toEqual(0x1f);
- expect(cpu.data[TIFR0]).toEqual(OCF0A); // TOV0 clear
+ expect(tcnt).toEqual(0);
+ expect(cpu.data[TIFR0] & TOV0).toEqual(0); // TOV0 clear
});
it('should set the TOV bit when TOP == MAX in CTC mode (issue #75)', () => {
@@ -310,11 +318,16 @@ describe('timer', () => {
cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
cpu.cycles = 1;
cpu.tick();
- cpu.cycles = 2;
+
+ cpu.cycles++;
cpu.tick();
- const tcnt = cpu.readData(TCNT0);
- expect(tcnt).toEqual(0xff);
- expect(cpu.data[TIFR0]).toEqual(OCF0A | TOV0);
+ expect(cpu.readData(TCNT0)).toEqual(0xff);
+ expect(cpu.data[TIFR0] & TOV0).toEqual(0); // TOV clear
+
+ cpu.cycles++;
+ cpu.tick();
+ expect(cpu.readData(TCNT0)).toEqual(0);
+ expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0); // TOV set
});
it('should not set the TOV bit twice on overflow (issue #80)', () => {
@@ -328,16 +341,15 @@ describe('timer', () => {
cpu.cycles = 1;
cpu.tick();
- cpu.cycles = 2;
+ cpu.cycles++;
cpu.tick();
expect(cpu.readData(TCNT0)).toEqual(0xff);
- expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0);
- cpu.data[TIFR0] &= ~TOV0; // Clear the TOV0 bit
+ expect(cpu.data[TIFR0] & TOV0).toEqual(0); // TOV clear
- cpu.cycles = 3;
+ cpu.cycles++;
cpu.tick();
expect(cpu.readData(TCNT0)).toEqual(0);
- expect(cpu.data[TIFR0] & TOV0).toEqual(0);
+ expect(cpu.data[TIFR0] & TOV0).toEqual(TOV0); // TOV set
});
it('should set OCF0B flag when timer equals OCRB', () => {
diff --git a/src/peripherals/timer.ts b/src/peripherals/timer.ts
index b1a64d9..e620459 100644
--- a/src/peripherals/timer.ts
+++ b/src/peripherals/timer.ts
@@ -481,20 +481,13 @@ export class AVRTimer {
// OCRUpdateMode.Bottom only occurs in Phase Correct modes, handled by phasePwmCount().
// Thus we only handle TOVUpdateMode.Top or TOVUpdateMode.Max here.
- if (
- (newVal === TOP || (overflow && val < TOP)) &&
- (this.tovUpdateMode == TOVUpdateMode.Top || TOP === this.MAX)
- ) {
+ if (overflow && (this.tovUpdateMode == TOVUpdateMode.Top || TOP === this.MAX)) {
cpu.setInterruptFlag(this.OVF);
}
}
}
if (this.tcntUpdated) {
- const { TOP } = this;
this.tcnt = this.tcntNext;
- if (this.tcnt === TOP && (this.tovUpdateMode == TOVUpdateMode.Top || TOP === this.MAX)) {
- cpu.setInterruptFlag(this.OVF);
- }
this.tcntUpdated = false;
}
if (this.updateDivider) {