diff options
| author | Uri Shaked | 2020-12-12 14:10:31 +0200 |
|---|---|---|
| committer | Uri Shaked | 2020-12-12 14:10:31 +0200 |
| commit | 18a19dcbd701f944a066b3e455464849820bf2f6 (patch) | |
| tree | 92c96d6f450685f5a6269b56962b99cfa05e7914 /src/cpu | |
| parent | chore(demo): upgrade monaco editor to 0.21.2 (diff) | |
| download | avr8js-18a19dcbd701f944a066b3e455464849820bf2f6.tar.gz avr8js-18a19dcbd701f944a066b3e455464849820bf2f6.tar.bz2 avr8js-18a19dcbd701f944a066b3e455464849820bf2f6.zip | |
fix(cpu): event system issue
`updateClockEvent()` and `clearClockEvent()` would sometimes mess up the list of events.
This could cause unexpected behavior when you have multiple timers running.
Also added regression tests for these methods.
Diffstat (limited to '')
| -rw-r--r-- | src/cpu/cpu.spec.ts | 61 | ||||
| -rw-r--r-- | src/cpu/cpu.ts | 4 |
2 files changed, 63 insertions, 2 deletions
diff --git a/src/cpu/cpu.spec.ts b/src/cpu/cpu.spec.ts index a68f754..00fbcb3 100644 --- a/src/cpu/cpu.spec.ts +++ b/src/cpu/cpu.spec.ts @@ -5,4 +5,65 @@ describe('cpu', () => { const cpu = new CPU(new Uint16Array(1024), 0x1000); expect(cpu.SP).toEqual(0x10ff); }); + + describe('events', () => { + it('should execute queued events after the given number of cycles has passed', () => { + const cpu = new CPU(new Uint16Array(1024), 0x1000); + const events = []; + for (const i of [1, 4, 10]) { + cpu.addClockEvent(() => events.push([i, cpu.cycles]), i); + } + for (let i = 0; i < 10; i++) { + cpu.cycles++; + cpu.tick(); + } + expect(events).toEqual([ + [1, 1], + [4, 4], + [10, 10], + ]); + }); + + describe('updateClockEvent', () => { + it('should update the number of cycles for the given clock event', () => { + const cpu = new CPU(new Uint16Array(1024), 0x1000); + const events = []; + const callbacks = []; + for (const i of [1, 4, 10]) { + callbacks[i] = cpu.addClockEvent(() => events.push([i, cpu.cycles]), i); + } + cpu.updateClockEvent(callbacks[4], 2); + cpu.updateClockEvent(callbacks[1], 12); + for (let i = 0; i < 14; i++) { + cpu.cycles++; + cpu.tick(); + } + expect(events).toEqual([ + [4, 2], + [10, 10], + [1, 12], + ]); + }); + + describe('clearClockEvent', () => { + it('should remove the given clock event', () => { + const cpu = new CPU(new Uint16Array(1024), 0x1000); + const events = []; + const callbacks = []; + for (const i of [1, 4, 10]) { + callbacks[i] = cpu.addClockEvent(() => events.push([i, cpu.cycles]), i); + } + cpu.clearClockEvent(callbacks[4]); + for (let i = 0; i < 10; i++) { + cpu.cycles++; + cpu.tick(); + } + expect(events).toEqual([ + [1, 1], + [10, 10], + ]); + }); + }); + }); + }); }); diff --git a/src/cpu/cpu.ts b/src/cpu/cpu.ts index fb98786..e7a2544 100644 --- a/src/cpu/cpu.ts +++ b/src/cpu/cpu.ts @@ -186,7 +186,7 @@ export class CPU implements ICPU { } updateClockEvent(callback: AVRClockEventCallback, cycles: number) { - const entry = this.clockEvents.find((item) => (item.callback = callback)); + const entry = this.clockEvents.find((item) => item.callback === callback); if (entry) { entry.cycles = this.cycles + Math.max(1, cycles); this.updateClockEvents(); @@ -196,7 +196,7 @@ export class CPU implements ICPU { } clearClockEvent(callback: AVRClockEventCallback) { - const index = this.clockEvents.findIndex((item) => (item.callback = callback)); + const index = this.clockEvents.findIndex((item) => item.callback === callback); if (index >= 0) { this.clockEvents.splice(index, 1); this.updateClockEvents(); |
