Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libgambatte/src/mem/rtc.cpp
2 views
1
/***************************************************************************
2
* Copyright (C) 2007 by Sindre AamÄs *
3
* [email protected] *
4
* *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License version 2 as *
7
* published by the Free Software Foundation. *
8
* *
9
* This program is distributed in the hope that it will be useful, *
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
* GNU General Public License version 2 for more details. *
13
* *
14
* You should have received a copy of the GNU General Public License *
15
* version 2 along with this program; if not, write to the *
16
* Free Software Foundation, Inc., *
17
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18
***************************************************************************/
19
#include "rtc.h"
20
#include "../savestate.h"
21
#include <cstdlib>
22
23
namespace gambatte {
24
25
Rtc::Rtc()
26
: activeData(NULL),
27
activeSet(NULL),
28
baseTime(0),
29
haltTime(0),
30
index(5),
31
dataDh(0),
32
dataDl(0),
33
dataH(0),
34
dataM(0),
35
dataS(0),
36
enabled(false),
37
lastLatchData(false),
38
timeCB(0)
39
{
40
}
41
42
void Rtc::doLatch() {
43
std::uint32_t tmp = ((dataDh & 0x40) ? haltTime : timeCB()) - baseTime;
44
45
while (tmp > 0x1FF * 86400) {
46
baseTime += 0x1FF * 86400;
47
tmp -= 0x1FF * 86400;
48
dataDh |= 0x80;
49
}
50
51
dataDl = (tmp / 86400) & 0xFF;
52
dataDh &= 0xFE;
53
dataDh |= ((tmp / 86400) & 0x100) >> 8;
54
tmp %= 86400;
55
56
dataH = tmp / 3600;
57
tmp %= 3600;
58
59
dataM = tmp / 60;
60
tmp %= 60;
61
62
dataS = tmp;
63
}
64
65
void Rtc::doSwapActive() {
66
if (!enabled || index > 4) {
67
activeData = NULL;
68
activeSet = NULL;
69
} else switch (index) {
70
case 0x00:
71
activeData = &dataS;
72
activeSet = &Rtc::setS;
73
break;
74
case 0x01:
75
activeData = &dataM;
76
activeSet = &Rtc::setM;
77
break;
78
case 0x02:
79
activeData = &dataH;
80
activeSet = &Rtc::setH;
81
break;
82
case 0x03:
83
activeData = &dataDl;
84
activeSet = &Rtc::setDl;
85
break;
86
case 0x04:
87
activeData = &dataDh;
88
activeSet = &Rtc::setDh;
89
break;
90
}
91
}
92
93
void Rtc::loadState(const SaveState &state) {
94
baseTime = state.rtc.baseTime;
95
haltTime = state.rtc.haltTime;
96
dataDh = state.rtc.dataDh;
97
dataDl = state.rtc.dataDl;
98
dataH = state.rtc.dataH;
99
dataM = state.rtc.dataM;
100
dataS = state.rtc.dataS;
101
lastLatchData = state.rtc.lastLatchData;
102
103
doSwapActive();
104
}
105
106
void Rtc::setDh(const unsigned new_dh) {
107
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
108
const std::uint32_t old_highdays = ((unixtime - baseTime) / 86400) & 0x100;
109
baseTime += old_highdays * 86400;
110
baseTime -= ((new_dh & 0x1) << 8) * 86400;
111
112
if ((dataDh ^ new_dh) & 0x40) {
113
if (new_dh & 0x40)
114
haltTime = timeCB();
115
else
116
baseTime += timeCB() - haltTime;
117
}
118
}
119
120
void Rtc::setDl(const unsigned new_lowdays) {
121
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
122
const std::uint32_t old_lowdays = ((unixtime - baseTime) / 86400) & 0xFF;
123
baseTime += old_lowdays * 86400;
124
baseTime -= new_lowdays * 86400;
125
}
126
127
void Rtc::setH(const unsigned new_hours) {
128
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
129
const std::uint32_t old_hours = ((unixtime - baseTime) / 3600) % 24;
130
baseTime += old_hours * 3600;
131
baseTime -= new_hours * 3600;
132
}
133
134
void Rtc::setM(const unsigned new_minutes) {
135
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
136
const std::uint32_t old_minutes = ((unixtime - baseTime) / 60) % 60;
137
baseTime += old_minutes * 60;
138
baseTime -= new_minutes * 60;
139
}
140
141
void Rtc::setS(const unsigned new_seconds) {
142
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
143
baseTime += (unixtime - baseTime) % 60;
144
baseTime -= new_seconds;
145
}
146
147
SYNCFUNC(Rtc)
148
{
149
EBS(activeData, 0);
150
EVS(activeData, &dataS, 1);
151
EVS(activeData, &dataM, 2);
152
EVS(activeData, &dataH, 3);
153
EVS(activeData, &dataDl, 4);
154
EVS(activeData, &dataDh, 5);
155
EES(activeData, NULL);
156
157
EBS(activeSet, 0);
158
EVS(activeSet, &Rtc::setS, 1);
159
EVS(activeSet, &Rtc::setM, 2);
160
EVS(activeSet, &Rtc::setH, 3);
161
EVS(activeSet, &Rtc::setDl, 4);
162
EVS(activeSet, &Rtc::setDh, 5);
163
EES(activeSet, NULL);
164
165
NSS(baseTime);
166
NSS(haltTime);
167
NSS(index);
168
NSS(dataDh);
169
NSS(dataDl);
170
NSS(dataH);
171
NSS(dataM);
172
NSS(dataS);
173
NSS(enabled);
174
NSS(lastLatchData);
175
}
176
177
}
178
179