aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/peripherals/timer.spec.ts21
-rw-r--r--src/peripherals/timer.ts7
2 files changed, 17 insertions, 11 deletions
diff --git a/src/peripherals/timer.spec.ts b/src/peripherals/timer.spec.ts
index 5a2d243..7854bf9 100644
--- a/src/peripherals/timer.spec.ts
+++ b/src/peripherals/timer.spec.ts
@@ -67,7 +67,8 @@ describe('timer', () => {
it('should update timer every tick when prescaler is 1', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
- cpu.data[TCCR0B] = CS00; // Set prescaler to 1
+ cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
+ timer.tick();
cpu.cycles = 1;
timer.tick();
const tcnt = cpu.readData(TCNT0);
@@ -77,7 +78,8 @@ describe('timer', () => {
it('should update timer every 64 ticks when prescaler is 3', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
- cpu.data[TCCR0B] = CS01 | CS00; // Set prescaler to 64
+ cpu.writeData(TCCR0B, CS01 | CS00); // Set prescaler to 64
+ timer.tick();
cpu.cycles = 64;
timer.tick();
const tcnt = cpu.readData(TCNT0);
@@ -87,7 +89,7 @@ describe('timer', () => {
it('should not update timer if it has been disabled', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
- cpu.data[TCCR0B] = 0; // No prescaler (timer disabled)
+ cpu.writeData(TCCR0B, 0); // No prescaler (timer disabled)
cpu.cycles = 100000;
timer.tick();
const tcnt = cpu.readData(TCNT0);
@@ -98,8 +100,8 @@ describe('timer', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
cpu.writeData(TCNT0, 0xff);
+ cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
timer.tick();
- cpu.data[TCCR0B] = CS00; // Set prescaler to 1
cpu.cycles = 1;
timer.tick();
const tcnt = cpu.readData(TCNT0);
@@ -111,10 +113,10 @@ describe('timer', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
cpu.writeData(TCNT0, 0xff);
+ cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
timer.tick();
cpu.writeData(OCR0A, 0x7f);
cpu.writeData(TCCR0A, WGM01 | WGM00); // WGM: Fast PWM
- cpu.data[TCCR0B] = CS00; // Set prescaler to 1
cpu.cycles = 1;
timer.tick();
const tcnt = cpu.readData(TCNT0);
@@ -126,8 +128,8 @@ describe('timer', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
cpu.writeData(TCNT0, 0xff);
+ cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
timer.tick();
- cpu.data[TCCR0B] = CS00; // Set prescaler to 1
cpu.data[TIMSK0] = TOIE0;
cpu.data[SREG] = 0x80; // SREG: I-------
cpu.cycles = 1;
@@ -143,8 +145,8 @@ describe('timer', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
cpu.writeData(TCNT0, 0xff);
+ cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
timer.tick();
- cpu.data[TCCR0B] = CS00; // Set prescaler to 1
cpu.data[TIMSK0] = TOIE0;
cpu.data[SREG] = 0x0; // SREG: --------
cpu.cycles = 1;
@@ -158,8 +160,8 @@ describe('timer', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer0Config);
cpu.writeData(TCNT0, 0xff);
+ cpu.writeData(TCCR0B, CS00); // Set prescaler to 1
timer.tick();
- cpu.data[TCCR0B] = CS00; // Set prescaler to 1
cpu.data[TIMSK0] = 0;
cpu.data[SREG] = 0x80; // SREG: I-------
cpu.cycles = 1;
@@ -289,7 +291,8 @@ describe('timer', () => {
it('timer2 should count every 256 ticks when prescaler is 6 (issue #5)', () => {
const cpu = new CPU(new Uint16Array(0x1000));
const timer = new AVRTimer(cpu, timer2Config);
- cpu.data[TCCR2B] = CS22 | CS21; // Set prescaler to 256
+ cpu.writeData(TCCR2B, CS22 | CS21); // Set prescaler to 256
+ timer.tick();
cpu.cycles = 511;
timer.tick();
diff --git a/src/peripherals/timer.ts b/src/peripherals/timer.ts
index 315d725..dc1302a 100644
--- a/src/peripherals/timer.ts
+++ b/src/peripherals/timer.ts
@@ -231,6 +231,7 @@ export class AVRTimer {
private compB: CompBitsValue;
private tcntUpdated = false;
private countingUp = true;
+ private divider = 0;
// This is the temporary register used to access 16-bit registers (section 16.3 of the datasheet)
private highByteTemp: u8 = 0;
@@ -283,12 +284,14 @@ export class AVRTimer {
cpu.writeHooks[config.TCCRB] = (value) => {
this.cpu.data[config.TCCRB] = value;
this.tcntUpdated = true;
+ this.divider = this.config.dividers[this.CS];
this.updateWGMConfig();
return true;
};
}
reset() {
+ this.divider = 0;
this.lastCycle = 0;
this.ocrA = 0;
this.ocrB = 0;
@@ -342,8 +345,8 @@ export class AVRTimer {
}
tick() {
- const divider = this.config.dividers[this.CS];
- const delta = this.cpu.cycles - this.lastCycle;
+ const { divider, lastCycle } = this;
+ const delta = this.cpu.cycles - lastCycle;
if (divider && delta >= divider) {
const counterDelta = Math.floor(delta / divider);
this.lastCycle += counterDelta * divider;