Skip to content

Commit 09f2385

Browse files
committed
fix(interrupt): broken on ATmega2560
close #58
1 parent 0d2405c commit 09f2385

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/cpu/interrupt.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,23 @@ describe('avrInterrupt', () => {
1616
expect(cpu.data[0x7f]).toEqual(0x5); // Return addr high
1717
expect(cpu.data[95]).toEqual(0b00000001); // SREG: -------C
1818
});
19+
20+
it('should push a 3-byte return address when running in 22-bit PC mode (issue #58)', () => {
21+
const cpu = new CPU(new Uint16Array(0x80000));
22+
expect(cpu.pc22Bits).toEqual(true);
23+
24+
cpu.pc = 0x10520;
25+
cpu.data[94] = 0;
26+
cpu.data[93] = 0x80; // SP <- 0x80
27+
cpu.data[95] = 0b10000001; // SREG <- I------C
28+
29+
avrInterrupt(cpu, 5);
30+
expect(cpu.cycles).toEqual(2);
31+
expect(cpu.pc).toEqual(5);
32+
expect(cpu.data[93]).toEqual(0x7d); // SP should decrement by 3
33+
expect(cpu.data[0x80]).toEqual(0x20); // Return addr low
34+
expect(cpu.data[0x7f]).toEqual(0x05); // Return addr high
35+
expect(cpu.data[0x7e]).toEqual(0x1); // Return addr extended
36+
expect(cpu.data[95]).toEqual(0b00000001); // SREG: -------C
37+
});
1938
});

src/cpu/interrupt.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ export function avrInterrupt(cpu: ICPU, addr: number) {
1212
const sp = cpu.dataView.getUint16(93, true);
1313
cpu.data[sp] = cpu.pc & 0xff;
1414
cpu.data[sp - 1] = (cpu.pc >> 8) & 0xff;
15-
cpu.dataView.setUint16(93, sp - 2, true);
15+
if (cpu.pc22Bits) {
16+
cpu.data[sp - 2] = (cpu.pc >> 16) & 0xff;
17+
}
18+
cpu.dataView.setUint16(93, sp - (cpu.pc22Bits ? 3 : 2), true);
1619
cpu.data[95] &= 0x7f; // clear global interrupt flag
1720
cpu.cycles += 2;
1821
cpu.pc = addr;

0 commit comments

Comments
 (0)