diff options
| -rw-r--r-- | src/index.ts | 1 | ||||
| -rw-r--r-- | src/interrupt.spec.ts | 18 | ||||
| -rw-r--r-- | src/interrupt.ts | 11 |
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; +} |
