aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/index.ts1
-rw-r--r--src/interrupt.spec.ts18
-rw-r--r--src/interrupt.ts11
3 files changed, 30 insertions, 0 deletions
diff --git a/src/index.ts b/src/index.ts
index 038ff16..8a474a4 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,2 +1,3 @@
export { CPU, ICPU, ICPUMemoryHook, ICPUMemoryHooks } from './cpu';
export { avrInstruction } from './instruction';
+export { avrInterrupt } from './interrupt';
diff --git a/src/interrupt.spec.ts b/src/interrupt.spec.ts
new file mode 100644
index 0000000..06979ed
--- /dev/null
+++ b/src/interrupt.spec.ts
@@ -0,0 +1,18 @@
+import { CPU } from './cpu';
+import { avrInterrupt } from './interrupt';
+
+describe('avrInterrupt', () => {
+ it('should execute interrupt handler', () => {
+ const cpu = new CPU(new Uint16Array(0x8000));
+ cpu.pc = 0x520;
+ cpu.data[93] = 0x80; // SP <- 0x80
+ cpu.data[95] = 0b10000001; // SREG <- I------C
+ avrInterrupt(cpu, 5);
+ expect(cpu.cycles).toEqual(2);
+ expect(cpu.pc).toEqual(5);
+ expect(cpu.data[93]).toEqual(0x7e); // SP
+ expect(cpu.data[0x80]).toEqual(0x20); // Return addr low
+ expect(cpu.data[0x7f]).toEqual(0x5); // Return addr high
+ expect(cpu.data[95]).toEqual(0b00000001); // SREG: -------C
+ });
+});
diff --git a/src/interrupt.ts b/src/interrupt.ts
new file mode 100644
index 0000000..d833a3a
--- /dev/null
+++ b/src/interrupt.ts
@@ -0,0 +1,11 @@
+import { ICPU } from './cpu';
+
+export function avrInterrupt(cpu: ICPU, addr: number) {
+ const sp = cpu.dataView.getUint16(93, true);
+ cpu.data[sp] = cpu.pc & 0xff;
+ cpu.data[sp - 1] = (cpu.pc >> 8) & 0xff;
+ cpu.dataView.setUint16(93, sp - 2, true);
+ cpu.data[95] &= 0x7f; // clear global interrupt flag
+ cpu.cycles += 2;
+ cpu.pc = addr;
+}