aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cpu/cpu.ts5
-rw-r--r--src/peripherals/eeprom.spec.ts27
-rw-r--r--src/peripherals/eeprom.ts8
3 files changed, 35 insertions, 5 deletions
diff --git a/src/cpu/cpu.ts b/src/cpu/cpu.ts
index 2675d1d..fe3bf63 100644
--- a/src/cpu/cpu.ts
+++ b/src/cpu/cpu.ts
@@ -141,9 +141,10 @@ export class CPU {
}
updateInterruptEnable(interrupt: AVRInterruptConfig, registerValue: u8) {
- const { enableMask, flagRegister, flagMask } = interrupt;
+ const { enableMask, flagRegister, flagMask, inverseFlag } = interrupt;
if (registerValue & enableMask) {
- if (this.data[flagRegister] & flagMask) {
+ const bitSet = this.data[flagRegister] & flagMask;
+ if (inverseFlag ? !bitSet : bitSet) {
this.queueInterrupt(interrupt);
}
} else {
diff --git a/src/peripherals/eeprom.spec.ts b/src/peripherals/eeprom.spec.ts
index 8f08e47..a90116f 100644
--- a/src/peripherals/eeprom.spec.ts
+++ b/src/peripherals/eeprom.spec.ts
@@ -99,7 +99,30 @@ describe('EEPROM', () => {
cpu.writeData(EEDR, 0x55);
cpu.writeData(EEARL, 15);
cpu.writeData(EEARH, 0);
- cpu.writeData(EECR, EEMPE | EERIE);
+ cpu.writeData(EECR, EEMPE);
+ cpu.data[SREG] = 0x80; // SREG: I-------
+ cpu.writeData(EECR, EEPE | EERIE);
+ cpu.cycles += 1000;
+ cpu.tick();
+ // At this point, write shouldn't be complete yet
+ expect(cpu.data[EECR] & EEPE).toEqual(EEPE);
+ expect(cpu.pc).toEqual(0);
+ cpu.cycles += 10000000;
+ // And now, 10 million cycles later, it should.
+ cpu.tick();
+ expect(eepromBackend.memory[15]).toEqual(0x55);
+ expect(cpu.data[EECR] & EEPE).toEqual(0);
+ expect(cpu.pc).toEqual(0x2c); // EEPROM Ready interrupt
+ });
+
+ it('should clear the fire an interrupt when there is a pending interrupt and the interrupt flag is enabled (issue #110)', () => {
+ const cpu = new CPU(new Uint16Array(0x1000));
+ const eepromBackend = new EEPROMMemoryBackend(1024);
+ new AVREEPROM(cpu, eepromBackend);
+ cpu.writeData(EEDR, 0x55);
+ cpu.writeData(EEARL, 15);
+ cpu.writeData(EEARH, 0);
+ cpu.writeData(EECR, EEMPE);
cpu.data[SREG] = 0x80; // SREG: I-------
cpu.writeData(EECR, EEPE);
cpu.cycles += 1000;
@@ -112,6 +135,8 @@ describe('EEPROM', () => {
cpu.tick();
expect(eepromBackend.memory[15]).toEqual(0x55);
expect(cpu.data[EECR] & EEPE).toEqual(0);
+ cpu.writeData(EECR, EERIE);
+ cpu.tick();
expect(cpu.pc).toEqual(0x2c); // EEPROM Ready interrupt
});
diff --git a/src/peripherals/eeprom.ts b/src/peripherals/eeprom.ts
index 8056847..045ffe8 100644
--- a/src/peripherals/eeprom.ts
+++ b/src/peripherals/eeprom.ts
@@ -58,6 +58,7 @@ const EEMPE = 1 << 2;
const EERIE = 1 << 3;
const EEPM0 = 1 << 4;
const EEPM1 = 1 << 5;
+const EECR_WRITE_MASK = EEPE | EEMPE | EERIE | EEPM0 | EEPM1;
export class AVREEPROM {
/**
@@ -91,6 +92,9 @@ export class AVREEPROM {
const addr = (this.cpu.data[EEARH] << 8) | this.cpu.data[EEARL];
+ this.cpu.data[EECR] = (this.cpu.data[EECR] & ~EECR_WRITE_MASK) | (eecr & EECR_WRITE_MASK);
+ this.cpu.updateInterruptEnable(this.EER, eecr);
+
if (eecr & EERE) {
this.cpu.clearInterrupt(this.EER);
}
@@ -116,6 +120,7 @@ export class AVREEPROM {
if (eecr & EEPE) {
// If EEMPE is zero, setting EEPE will have no effect.
if (this.cpu.cycles >= this.writeEnabledCycles) {
+ this.cpu.data[EECR] &= ~EEPE;
return true;
}
// Check for write-in-progress
@@ -147,10 +152,9 @@ export class AVREEPROM {
// When EEPE has been set, the CPU is halted for two cycles before the
// next instruction is executed.
this.cpu.cycles += 2;
- return true;
}
- return false;
+ return true;
};
}
}
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.