-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtimer.c
More file actions
82 lines (71 loc) · 1.76 KB
/
Copy pathtimer.c
File metadata and controls
82 lines (71 loc) · 1.76 KB
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
#include "timer.h"
#include "cpu.h"
static uint16_t timer_divider_increase = 0;
static uint8_t timer_divider = 0;
static uint32_t timer_counter_increase = 0;
static uint8_t timer_counter = 0;
static uint8_t timer_ctrl = 0xF8;
static uint8_t timer_modulo = 0;
void timer_step (int cycles) {
timer_divider_increase += cycles;
if (timer_divider_increase >= 256) {
timer_divider_increase -= 256;
timer_divider++;
}
if ((timer_ctrl >> 2) & 0x1) {
int timer_increase_by = 0;
switch((timer_ctrl & 0x3)) {
case 0:
timer_increase_by = 256;
break;
case 1:
timer_increase_by = 16384;
break;
case 2:
timer_increase_by = 4096;
break;
case 3:
timer_increase_by = 1024;
break;
}
timer_counter_increase += (timer_increase_by * cycles);
if (timer_counter_increase >= 262144) {
timer_counter_increase -= 262144;
timer_counter++;
if (timer_counter == 0) {
timer_counter = timer_modulo;
cpu_request_interrupt(2);
}
}
}
}
void timer_write_reg (uint16_t addr, uint8_t val) {
switch (addr) {
case 0xff04:
timer_divider = 0;
break;
case 0xff05:
timer_counter = 0;
break;
case 0xff06:
timer_modulo = val;
break;
case 0xff07:
timer_ctrl = val;
break;
}
}
uint8_t timer_read_reg (uint16_t addr) {
switch (addr) {
case 0xff04:
return timer_divider;
case 0xff05:
return timer_counter;
case 0xff06:
return timer_modulo;
case 0xff07:
return timer_ctrl;
default:
return 0xff;
}
}