2 FUJITSU FMR-30 Emulator 'eFMR-30'
4 Author : Takeda.Toshiya
26 DLL_PREFIX_I struct cur_time_s cur_time;
29 void RTC::initialize()
31 // load rtc regs image
32 memset(regs, 0, sizeof(regs));
33 regs[POWON] = 0x10; // cleared
35 FILEIO* fio = new FILEIO();
36 if(fio->Fopen(create_local_path(_T("RTC.BIN")), FILEIO_READ_BINARY)) {
37 fio->Fread(regs + 8, 32, 1);
43 // regs[POWON] &= 0x1f; // local power on
44 // regs[POWOF] = 0x80; // program power off
45 regs[POWON] = 0x10; // cleared
46 regs[POWOF] = 0x20; // illegal power off
53 get_host_time(&cur_time);
57 register_event_by_clock(this, EVENT_1HZ, CPU_CLOCKS, true, ®ister_id);
58 register_event_by_clock(this, EVENT_32HZ, CPU_CLOCKS >> 5, true, NULL);
64 regs[POFMI] = TO_BCD(cur_time.minute);
65 regs[POFH] = TO_BCD(cur_time.hour);
66 regs[POFD] = TO_BCD(cur_time.day);
68 // save rtc regs image
69 FILEIO* fio = new FILEIO();
70 if(fio->Fopen(create_local_path(_T("RTC.BIN")), FILEIO_WRITE_BINARY)) {
71 fio->Fwrite(regs + 8, 32, 1);
77 void RTC::write_io16(uint32_t addr, uint32_t data)
85 rtdsr &= ~(data & 0xe);
93 register_event(this, EVENT_DONE, 100, false, NULL);
102 uint32_t RTC::read_io16(uint32_t addr)
113 void RTC::event_callback(int event_id, int err)
115 if(event_id == EVENT_1HZ) {
117 if(cur_time.initialized) {
118 cur_time.increment();
120 get_host_time(&cur_time); // resync
121 cur_time.initialized = true;
123 read_from_cur_time();
128 } else if(event_id == EVENT_32HZ) {
131 } else if(event_id == EVENT_DONE) {
132 int ch = (rtadr >> 1) & 0x3f;
135 } else if(rtadr & 0x80) {
138 regs[ch] = (uint8_t)rtobr;
140 } else if(ch == POWON) {
141 regs[ch] = (regs[ch] & 0xe0) | (rtobr & 0x1f);
142 if((rtobr & 0xe0) == 0xc0) {
144 regs[ch] = (regs[ch] & 0x1f) | 0xc0;
146 } else if((rtobr & 0xe0) == 0xe0) {
151 } else if(7 <= ch && ch < 32) {
152 regs[ch] = (uint8_t)rtobr;
168 void RTC::read_from_cur_time()
170 regs[0] = TO_BCD(cur_time.second);
171 regs[1] = TO_BCD(cur_time.minute);
172 regs[2] = TO_BCD(cur_time.hour);
173 regs[3] = cur_time.day_of_week;
174 regs[4] = TO_BCD(cur_time.day);
175 regs[5] = TO_BCD(cur_time.month);
176 regs[6] = TO_BCD(cur_time.year);
179 void RTC::write_to_cur_time()
181 cur_time.second = FROM_BCD(regs[0]);
182 cur_time.minute = FROM_BCD(regs[1]);
183 cur_time.hour = FROM_BCD(regs[2]);
184 // cur_time.day_of_week = regs[3];
185 cur_time.day = FROM_BCD(regs[4]);
186 cur_time.month = FROM_BCD(regs[5]);
187 cur_time.year = FROM_BCD(regs[6]);
188 cur_time.update_year();
189 cur_time.update_day_of_week();
192 cancel_event(this, register_id);
193 register_event_by_clock(this, EVENT_1HZ, CPU_CLOCKS, true, ®ister_id);
196 void RTC::update_checksum()
199 for(int i = 8; i < 32; i++) {
200 sum += regs[i] & 0xf;
201 sum += (regs[i] >> 4) & 0xf;
203 uint8_t ckh = (sum >> 6) & 0xf;
204 uint8_t ckm = (sum >> 2) & 0xf;
205 uint8_t ckl = (sum >> 0) & 3;
207 regs[CKHM] = ckh | (ckm << 4);
208 regs[CKL] = (regs[CKL] & 0xf0) | ckl | 0xc;
211 void RTC::update_intr()
213 d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, (rtcmr & rtdsr & 0xe) ? 1 : 0, 1);
216 #define STATE_VERSION 1
218 #include "../../statesub.h"
220 void RTC::decl_state()
222 enter_decl_state(STATE_VERSION);
224 DECL_STATE_ENTRY_CUR_TIME_T(cur_time);
225 DECL_STATE_ENTRY_INT32(register_id);
226 DECL_STATE_ENTRY_UINT16(rtcmr);
227 DECL_STATE_ENTRY_UINT16(rtdsr);
228 DECL_STATE_ENTRY_UINT16(rtadr);
229 DECL_STATE_ENTRY_UINT16(rtobr);
230 DECL_STATE_ENTRY_UINT16(rtibr);
231 DECL_STATE_ENTRY_1D_ARRAY(regs, sizeof(regs));
236 void RTC::save_state(FILEIO* state_fio)
238 if(state_entry != NULL) {
239 state_entry->save_state(state_fio);
242 // state_fio->FputUint32(STATE_VERSION);
243 // state_fio->FputInt32(this_device_id);
245 // cur_time.save_state((void *)state_fio);
246 // state_fio->FputInt32(register_id);
247 // state_fio->FputUint16(rtcmr);
248 // state_fio->FputUint16(rtdsr);
249 // state_fio->FputUint16(rtadr);
250 // state_fio->FputUint16(rtobr);
251 // state_fio->FputUint16(rtibr);
252 // state_fio->Fwrite(regs, sizeof(regs), 1);
255 bool RTC::load_state(FILEIO* state_fio)
258 if(state_entry != NULL) {
259 mb = state_entry->load_state(state_fio);
265 // if(state_fio->FgetUint32() != STATE_VERSION) {
268 // if(state_fio->FgetInt32() != this_device_id) {
271 // if(!cur_time.load_state((void *)state_fio)) {
274 // register_id = state_fio->FgetInt32();
275 // rtcmr = state_fio->FgetUint16();
276 // rtdsr = state_fio->FgetUint16();
277 // rtadr = state_fio->FgetUint16();
278 // rtobr = state_fio->FgetUint16();
279 // rtibr = state_fio->FgetUint16();
280 // state_fio->Fread(regs, sizeof(regs), 1);