diff options
| author | Uri Shaked | 2020-09-02 23:23:21 +0300 |
|---|---|---|
| committer | Uri Shaked | 2020-09-02 23:23:21 +0300 |
| commit | 673cbaf83872e8a81370f215c4644185eaf1f783 (patch) | |
| tree | 11552483c8cb84f03f0322cab07ac51959bac15b | |
| parent | 0.11.1 (diff) | |
| download | avr8js-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.ts | 21 | ||||
| -rw-r--r-- | src/peripherals/timer.ts | 7 |
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; |
