-
Notifications
You must be signed in to change notification settings - Fork 7
/
Via.h
85 lines (82 loc) · 1.61 KB
/
Via.h
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
85
#pragma once
#include "types.h"
class Via
{
public:
Via() : checkIrqCallback(dummyChkIrqCallback) {
reset();
}
enum {
IRQM_CTRL = 0x80,
IRQM_T1 = 0x40,
IRQM_T2 = 0x20,
IRQM_CB1 = 0x10,
IRQM_CB2 = 8,
IRQM_SR = 4,
IRQM_CA1 = 2,
IRQM_CA2 = 1
};
enum viaPins {
INPUTA = 0, INPUTB, INPUTCA1, INPUTCA2, INPUTCB1, INPUTCB2
};
unsigned char pra, ddra, prb, ddrb;
unsigned short t1c, t1l, t2c, t2l, t1t, t2t, t1r, t2r;
unsigned char sr, acr, pcr, ifr, ier;
unsigned char pb7, pb6;
bool pb7trigger;
unsigned char reg[16];
void* callBackParam;
void write(unsigned int r, unsigned char value);
unsigned char read(unsigned int r);
CallBackFunctorInt8 checkIrqCallback;
void reset();
void countTimers();
void setCheckIrqCallback(void* p, CallBackFunctorInt8 irqCallback_) {
checkIrqCallback = irqCallback_;
callBackParam = p;
}
static void dummyChkIrqCallback(void*, unsigned char) {
return;
}
};
inline void Via::countTimers()
{
if (t1r) {
t1c = t1l;
t1r = 0;
} else {
t1c--;
if (t1c == 0xFFFF) {
// always reload from latch
t1r = 1;
// free-run mode?
bool cont = !!(acr & 0x40);
if (cont || !t1t) {
t1t = cont ? (t1t ^ 1) : 1;
ifr |= IRQM_T1;
checkIrqCallback(callBackParam, ifr & ier);
}
if ((acr & 0x80) && ((acr & 0x40) || !pb7trigger)) {
pb7 ^= 0x80;
pb7trigger = true;
}
}
}
// not counting falling edge of PB6?
if (!(acr & 0x20)) {
if (t2r) {
t2r = 0;
}
else {
t2c--;
if (t2c == 0xFFFF) {
// always one-shot
if (!t2t) {
t2t = 1;
ifr |= IRQM_T2;
checkIrqCallback(callBackParam, ifr & ier);
}
}
}
}
}