1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
import { CPU } from './cpu';
import { AVRTimer, timer0Config } from './timer';
describe('timer', () => {
let cpu: CPU;
beforeEach(() => {
cpu = new CPU(new Uint16Array(0x1000));
});
it('should update timer every tick when prescaler is 1', () => {
const timer = new AVRTimer(cpu, timer0Config);
cpu.data[0x45] = 0x1; // TCCR0B.CS <- 1
cpu.cycles = 1;
timer.tick();
expect(cpu.data[0x46]).toEqual(1); // TCNT should be 1
});
it('should update timer every 64 ticks when prescaler is 3', () => {
const timer = new AVRTimer(cpu, timer0Config);
cpu.data[0x45] = 0x3; // TCCR0B.CS <- 3
cpu.cycles = 64;
timer.tick();
expect(cpu.data[0x46]).toEqual(1); // TCNT should be 1
});
it('should not update timer if it has been disabled', () => {
const timer = new AVRTimer(cpu, timer0Config);
cpu.data[0x45] = 0; // TCCR0B.CS <- 0
cpu.cycles = 100000;
timer.tick();
expect(cpu.data[0x46]).toEqual(0); // TCNT should stay 0
});
it('should set TOV if timer overflows', () => {
const timer = new AVRTimer(cpu, timer0Config);
cpu.data[0x46] = 0xff; // TCNT0 <- 0xff
cpu.data[0x45] = 0x1; // TCCR0B.CS <- 1
cpu.cycles = 1;
timer.tick();
expect(cpu.data[0x46]).toEqual(0); // TCNT should be 0
expect(cpu.data[0x35]).toEqual(1); // TOV bit in TIFR
});
it('should generate an overflow interrupt if timer overflows and interrupts enabled', () => {
const timer = new AVRTimer(cpu, timer0Config);
cpu.data[0x46] = 0xff; // TCNT0 <- 0xff
cpu.data[0x45] = 0x1; // TCCR0B.CS <- 1
cpu.data[0x6e] = 0x1; // TIMSK0: TOIE0
cpu.data[95] = 0x80; // SREG: I-------
cpu.cycles = 1;
timer.tick();
expect(cpu.data[0x46]).toEqual(0); // TCNT should be 0
expect(cpu.data[0x35]).toEqual(0); // TOV bit in TIFR should be clear
expect(cpu.pc).toEqual(0x20);
expect(cpu.cycles).toEqual(3);
});
it('should not generate an overflow interrupt when global interrupts disabled', () => {
const timer = new AVRTimer(cpu, timer0Config);
cpu.data[0x46] = 0xff; // TCNT0 <- 0xff
cpu.data[0x45] = 0x1; // TCCR0B.CS <- 1
cpu.data[0x6e] = 0x1; // TIMSK0: TOIE0
cpu.data[95] = 0x0; // SREG: --------
cpu.cycles = 1;
timer.tick();
expect(cpu.data[0x35]).toEqual(1); // TOV bit in TIFR should be set
expect(cpu.pc).toEqual(0);
expect(cpu.cycles).toEqual(1);
});
it('should not generate an overflow interrupt when TOIE0 is clear', () => {
const timer = new AVRTimer(cpu, timer0Config);
cpu.data[0x46] = 0xff; // TCNT0 <- 0xff
cpu.data[0x45] = 0x1; // TCCR0B.CS <- 1
cpu.data[0x6e] = 0; // TIMSK0: clear
cpu.data[95] = 0x80; // SREG: I-------
cpu.cycles = 1;
timer.tick();
expect(cpu.data[0x35]).toEqual(1); // TOV bit in TIFR should be set
expect(cpu.pc).toEqual(0);
expect(cpu.cycles).toEqual(1);
});
});
|