diff options
Diffstat (limited to 'src/timer.spec.ts')
| -rw-r--r-- | src/timer.spec.ts | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/timer.spec.ts b/src/timer.spec.ts index b7d96a9..dd45cee 100644 --- a/src/timer.spec.ts +++ b/src/timer.spec.ts @@ -42,6 +42,30 @@ describe('timer', () => { expect(cpu.data[0x35]).toEqual(1); // TOV bit in TIFR }); + it('should set TOV if timer overflows in PWM Phase Correct mode', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.data[0x46] = 0xff; // TCNT0 <- 0xff + cpu.writeData(0x47, 0x7f); // OCRA <- 0x7f + cpu.writeData(0x44, 0x1); // WGM0 <- 1 (PWM, Phase Correct) + cpu.data[0x45] = 0x1; // TCCR0B.CS <- 1 + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x46]).toEqual(0); // TCNT should be 0 + expect(cpu.data[0x35]).toEqual(1); // TOV bit in TIFR + }); + + it('should set TOV if timer overflows in FAST PWM mode', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.data[0x46] = 0xff; // TCNT0 <- 0xff + cpu.writeData(0x47, 0x7f); // OCRA <- 0x7f + cpu.writeData(0x44, 0x3); // WGM0 <- 3 (FAST PWM) + cpu.data[0x45] = 0x1; // TCCR0B.CS <- 1 + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x46]).toEqual(0); // TCNT should be 0 + expect(cpu.data[0x35]).toEqual(1); // TOV bit in TIFR + }); + it('should generate an overflow interrupt if timer overflows and interrupts enabled', () => { const timer = new AVRTimer(cpu, timer0Config); cpu.data[0x46] = 0xff; // TCNT0 <- 0xff @@ -81,4 +105,87 @@ describe('timer', () => { expect(cpu.pc).toEqual(0); expect(cpu.cycles).toEqual(1); }); + + it('should set OCF0A flag when timer equals OCRA', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.writeData(0x46, 0x10); // TCNT0 <- 0x10 + cpu.writeData(0x47, 0x11); // OCR0A <- 0x11 + cpu.writeData(0x44, 0x0); // WGM0 <- 0 (Normal) + cpu.writeData(0x45, 0x1); // TCCR0B.CS <- 1 + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x35]).toEqual(2); // TIFR0 should have OCF0A bit on + expect(cpu.pc).toEqual(0); + expect(cpu.cycles).toEqual(1); + }); + + it('should clear the timer in CTC mode if it equals to OCRA', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.writeData(0x46, 0x10); // TCNT0 <- 0x10 + cpu.writeData(0x47, 0x11); // OCR0A <- 0x11 + cpu.writeData(0x44, 0x2); // WGM0 <- 2 (CTC) + cpu.writeData(0x45, 0x1); // TCCR0B.CS <- 1 + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x46]).toEqual(0); // TCNT should be 0 + expect(cpu.pc).toEqual(0); + expect(cpu.cycles).toEqual(1); + }); + + it('should set OCF0B flag when timer equals OCRB', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.writeData(0x46, 0x10); // TCNT0 <- 0x50 + cpu.writeData(0x48, 0x11); // OCR0B <- 0x51 + cpu.writeData(0x44, 0x0); // WGM0 <- 0 (Normal) + cpu.writeData(0x45, 0x1); // TCCR0B.CS <- 1 + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x35]).toEqual(4); // TIFR0 should have OCF0B bit on + expect(cpu.pc).toEqual(0); + expect(cpu.cycles).toEqual(1); + }); + + it('should generate Timer Compare A interrupt when TCNT0 == TCNTA', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.writeData(0x46, 0x20); // TCNT0 <- 0x20 + cpu.writeData(0x47, 0x21); // OCR0A <- 0x21 + cpu.writeData(0x45, 0x1); // TCCR0B.CS <- 1 + cpu.writeData(0x6e, 0x2); // TIMSK0: OCIEA + cpu.writeData(95, 0x80); // SREG: I------- + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x46]).toEqual(0x21); // TCNT should be 0x21 + expect(cpu.data[0x35]).toEqual(0); // OCFA bit in TIFR should be clear + expect(cpu.pc).toEqual(0x1c); + expect(cpu.cycles).toEqual(3); + }); + + it('should not generate Timer Compare A interrupt when OCIEA is disabled', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.writeData(0x46, 0x20); // TCNT0 <- 0x20 + cpu.writeData(0x47, 0x21); // OCR0A <- 0x21 + cpu.writeData(0x45, 0x1); // TCCR0B.CS <- 1 + cpu.writeData(0x6e, 0); // TIMSK0 + cpu.writeData(95, 0x80); // SREG: I------- + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x46]).toEqual(0x21); // TCNT should be 0x21 + expect(cpu.pc).toEqual(0); + expect(cpu.cycles).toEqual(1); + }); + + it('should generate Timer Compare B interrupt when TCNT0 == TCNTB', () => { + const timer = new AVRTimer(cpu, timer0Config); + cpu.writeData(0x46, 0x20); // TCNT0 <- 0x20 + cpu.writeData(0x48, 0x21); // OCR0B <- 0x21 + cpu.writeData(0x45, 0x1); // TCCR0B.CS <- 1 + cpu.writeData(0x6e, 0x4); // TIMSK0: OCIEB + cpu.writeData(95, 0x80); // SREG: I------- + cpu.cycles = 1; + timer.tick(); + expect(cpu.data[0x46]).toEqual(0x21); // TCNT should be 0x21 + expect(cpu.data[0x35]).toEqual(0); // OCFB bit in TIFR should be clear + expect(cpu.pc).toEqual(0x1e); + expect(cpu.cycles).toEqual(3); + }); }); |
