OSDN Git Service

[VM][BMJR][PASOPIA7][PV1000][PV2000][X07][YALKY][YS6464A] Apply new state framework...
[csp-qt/common_source_project-fm7.git] / source / src / vm / bubcom80 / rtc.cpp
1 /*
2         Systems Formulate BUBCOM80 Emulator 'eBUBCOM80'
3
4         Author : Takeda.Toshiya
5         Date   : 2018.05.11-
6
7         [ rtc ]
8 */
9
10 #include "rtc.h"
11
12 #define EVENT_1HZ       0
13
14 void RTC::initialize()
15 {
16         get_host_time(&cur_time);
17         
18         register_event_by_clock(this, EVENT_1HZ, CPU_CLOCKS, true, NULL);
19 }
20
21 void RTC::reset()
22 {
23         tmp_time = cur_time; // ???
24         ctrl = 0;
25 }
26
27 #define SET_DECIMAL_HI(t, v) \
28         t %= 10; \
29         t += (v) * 10
30 #define SET_DECIMAL_LO(t, v) \
31         t /= 10; \
32         t *= 10; \
33         t += (v)
34 #define GET_DECIMAL_HI(t) TO_BCD_HI(t)
35 #define GET_DECIMAL_LO(t) TO_BCD_LO(t)
36
37 void RTC::write_io8(uint32_t addr, uint32_t data)
38 {
39         switch(addr) {
40         case 0x3fed:
41                 if(ctrl == 0x80 && data != 0x80) {
42                         cur_time = tmp_time;
43                         cur_time.initialized = true;
44                 }
45                 if(data == 0xc0) {
46                         tmp_time = cur_time;
47                 }
48                 ctrl = data;
49                 break;
50         case 0x3fec:
51                 SET_DECIMAL_HI(tmp_time.year, data & 0x0f);
52                 tmp_time.update_year();
53                 tmp_time.update_day_of_week();
54                 break;
55         case 0x3feb:
56                 SET_DECIMAL_LO(tmp_time.year, data & 0x0f);
57                 tmp_time.update_day_of_week();
58                 break;
59         case 0x3fea:
60                 SET_DECIMAL_HI(tmp_time.month, data & 0x01);
61                 tmp_time.update_day_of_week();
62                 break;
63         case 0x3fe9:
64                 SET_DECIMAL_LO(tmp_time.month, data & 0x0f);
65                 tmp_time.update_day_of_week();
66                 break;
67         case 0x3fe8:
68                 SET_DECIMAL_HI(tmp_time.day, data & 0x03);
69                 tmp_time.update_day_of_week();
70                 break;
71         case 0x3fe7:
72                 SET_DECIMAL_LO(tmp_time.day, data & 0x0f);
73                 tmp_time.update_day_of_week();
74                 break;
75         case 0x3fe6:
76 //              tmp_time.day_of_week = data & 0x07;
77                 break;
78         case 0x3fe5:
79                 SET_DECIMAL_HI(tmp_time.hour, data & 0x03);
80                 break;
81         case 0x3fe4:
82                 SET_DECIMAL_LO(tmp_time.hour, data & 0x0f);
83                 break;
84         case 0x3fe3:
85                 SET_DECIMAL_HI(tmp_time.minute, data & 0x07);
86                 break;
87         case 0x3fe2:
88                 SET_DECIMAL_LO(tmp_time.minute, data & 0x0f);
89                 break;
90         case 0x3fe1:
91                 SET_DECIMAL_HI(tmp_time.second, data & 0x07);
92                 break;
93         case 0x3fe0:
94                 SET_DECIMAL_LO(tmp_time.second, data & 0x0f);
95                 break;
96         }
97 }
98
99 uint32_t RTC::read_io8(uint32_t addr)
100 {
101         switch(addr) {
102         case 0x3fed:
103                 return ctrl;
104         case 0x3fec:
105                 return GET_DECIMAL_HI(tmp_time.year);
106         case 0x3feb:
107                 return GET_DECIMAL_LO(tmp_time.year);
108         case 0x3fea:
109                 return GET_DECIMAL_HI(tmp_time.month);
110         case 0x3fe9:
111                 return GET_DECIMAL_LO(tmp_time.month);
112         case 0x3fe8:
113                 return GET_DECIMAL_HI(tmp_time.day);
114         case 0x3fe7:
115                 return GET_DECIMAL_LO(tmp_time.day);
116         case 0x3fe6:
117                 return tmp_time.day_of_week;
118         case 0x3fe5:
119                 return GET_DECIMAL_HI(tmp_time.hour);
120         case 0x3fe4:
121                 return GET_DECIMAL_LO(tmp_time.hour);
122         case 0x3fe3:
123                 return GET_DECIMAL_HI(tmp_time.minute);
124         case 0x3fe2:
125                 return GET_DECIMAL_LO(tmp_time.minute);
126         case 0x3fe1:
127                 return GET_DECIMAL_HI(tmp_time.second);
128         case 0x3fe0:
129                 return GET_DECIMAL_LO(tmp_time.second);
130         }
131         return 0xff;
132 }
133
134 void RTC::event_callback(int event_id, int err)
135 {
136         if(event_id == EVENT_1HZ) {
137                 // update calendar
138                 if(cur_time.initialized) {
139                         cur_time.increment();
140                 } else {
141                         get_host_time(&cur_time);       // resync
142                         cur_time.initialized = true;
143                 }
144         }
145 }
146
147 #define STATE_VERSION   1
148
149 #include "../../statesub.h"
150
151 // ToDo: DECL_STATE_foo() for FIFO:: and cur_time_t:: .
152 void RTC::decl_state()
153 {
154         state_entry = new csp_state_utils(STATE_VERSION, this_device_id, _T("RTC"));
155         DECL_STATE_ENTRY_UINT8(ctrl);
156 }
157
158 void RTC::save_state(FILEIO* state_fio)
159 {
160         //state_fio->FputUint32(STATE_VERSION);
161         //state_fio->FputInt32(this_device_id);
162         
163         if(state_entry != NULL) {
164                 state_entry->save_state(state_fio);
165         }
166         cur_time.save_state((void *)state_fio);
167         tmp_time.save_state((void *)state_fio);
168         //state_fio->FputUint8(ctrl);
169 }
170
171 bool RTC::load_state(FILEIO* state_fio)
172 {
173         bool mb = false;
174         if(state_entry != NULL) {
175                 mb = state_entry->load_state(state_fio);
176         }
177         if(!mb) return false;
178         //if(state_fio->FgetUint32() != STATE_VERSION) {
179         //      return false;
180         //}
181         //if(state_fio->FgetInt32() != this_device_id) {
182         //      return false;
183         //}
184         if(!cur_time.load_state((void *)state_fio)) {
185                 return false;
186         }
187         if(!tmp_time.load_state((void *)state_fio)) {
188                 return false;
189         }
190         //ctrl = state_fio->FgetUint8();
191         return true;
192 }
193