aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/peripherals/timer.spec.ts22
-rw-r--r--src/peripherals/timer.ts4
2 files changed, 24 insertions, 2 deletions
diff --git a/src/peripherals/timer.spec.ts b/src/peripherals/timer.spec.ts
index 68f6a66..a15672c 100644
--- a/src/peripherals/timer.spec.ts
+++ b/src/peripherals/timer.spec.ts
@@ -37,6 +37,7 @@ const ICR1 = 0x86;
const ICR1H = 0x87;
const OCR1A = 0x88;
const OCR1AH = 0x89;
+const OCR1B = 0x8a;
// Timer 2 Registers
const TCCR2B = 0xb1;
@@ -51,8 +52,11 @@ const TOIE0 = 1;
const OCF0A = 2;
const OCF0B = 4;
const OCF1A = 2;
+const OCF1B = 4;
const WGM00 = 1;
+const WGM10 = 1;
const WGM01 = 2;
+const WGM11 = 2;
const WGM12 = 8;
const WGM13 = 16;
const CS00 = 1;
@@ -258,6 +262,24 @@ describe('timer', () => {
expect(cpu.cycles).toEqual(2);
});
+ it('should set the OCF1A flag when OCR1A == 120 and the timer overflowed past 120 in WGM mode 15 (issue #94)', () => {
+ const cpu = new CPU(new Uint16Array(0x1000));
+ new AVRTimer(cpu, timer1Config);
+ cpu.writeData(TCNT1, 118);
+ cpu.writeData(OCR1A, 120);
+ cpu.writeData(OCR1B, 4); // To avoid getting the OCF1B flag set
+ cpu.writeData(TCCR1A, WGM10 | WGM11); // WGM: Fast PWM
+ cpu.writeData(TCCR1B, WGM12 | WGM13 | CS10); // Set prescaler to 1
+ cpu.cycles = 1;
+ cpu.tick();
+ cpu.cycles = 5;
+ cpu.tick();
+ expect(cpu.readData(TCNT1)).toEqual(1);
+ expect(cpu.data[TIFR1] & (OCF1A | OCF1B)).toEqual(OCF1A);
+ expect(cpu.pc).toEqual(0);
+ expect(cpu.cycles).toEqual(5);
+ });
+
it('should set OCF0A flag when timer equals OCRA', () => {
const cpu = new CPU(new Uint16Array(0x1000));
new AVRTimer(cpu, timer0Config);
diff --git a/src/peripherals/timer.ts b/src/peripherals/timer.ts
index e620459..c79cc7c 100644
--- a/src/peripherals/timer.ts
+++ b/src/peripherals/timer.ts
@@ -548,13 +548,13 @@ export class AVRTimer {
private timerUpdated(value: number, prevValue: number) {
const { ocrA, ocrB } = this;
const overflow = prevValue > value;
- if ((prevValue < ocrA || overflow) && value >= ocrA) {
+ if (((prevValue < ocrA || overflow) && value >= ocrA) || (prevValue < ocrA && overflow)) {
this.cpu.setInterruptFlag(this.OCFA);
if (this.compA) {
this.updateCompPin(this.compA, 'A');
}
}
- if ((prevValue < ocrB || overflow) && value >= ocrB) {
+ if (((prevValue < ocrB || overflow) && value >= ocrB) || (prevValue < ocrB && overflow)) {
this.cpu.setInterruptFlag(this.OCFB);
if (this.compB) {
this.updateCompPin(this.compB, 'B');
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.