aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUri Shaked2020-09-02 23:23:21 +0300
committerUri Shaked2020-09-02 23:23:21 +0300
commit673cbaf83872e8a81370f215c4644185eaf1f783 (patch)
tree11552483c8cb84f03f0322cab07ac51959bac15b
parent0.11.1 (diff)
downloadavr8js-673cbaf83872e8a81370f215c4644185eaf1f783.tar.gz
avr8js-673cbaf83872e8a81370f215c4644185eaf1f783.tar.bz2
avr8js-673cbaf83872e8a81370f215c4644185eaf1f783.zip
perf(timer): improve timer speed
cache the value of the clock divider
-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;
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.