OSDN Git Service

[VM][Qt][OSD][Genaral] Sync to upstream ; phase 1: Merege upstream 20151217.
[csp-qt/common_source_project-fm7.git] / source / src / vm / upd1990a.cpp
index 651ff2e..733b59f 100644 (file)
-/*\r
-       Skelton for retropc emulator\r
-\r
-       Author : Takeda.Toshiya\r
-       Date   : 2008.04.19-\r
-\r
-       [ uPD1990A / uPD4990A ]\r
-*/\r
-\r
-#include "upd1990a.h"\r
-#include "../fileio.h"\r
-\r
-#define EVENT_1SEC     0\r
-#define EVENT_TP       1\r
-\r
-void UPD1990A::initialize()\r
-{\r
-       // initialize rtc\r
-       emu->get_host_time(&cur_time);\r
-       \r
-       // register events\r
-       register_event(this, EVENT_1SEC, 1000000.0, true, &register_id_1sec);\r
-       register_id_tp = -1;\r
-}\r
-\r
-void UPD1990A::write_signal(int id, uint32 data, uint32 mask)\r
-{\r
-       if(id == SIG_UPD1990A_CLK) {\r
-               bool next = ((data & mask) != 0);\r
-               if(!clk && next) {\r
-                       if((mode & 0x0f) == 1) {\r
-                               uint64 bit = 1;\r
-#ifdef HAS_UPD4990A\r
-                               if(mode & 0x80) {\r
-                                       bit <<= (52 - 1);\r
-                               } else {\r
-#endif\r
-                                       bit <<= (40 - 1);\r
-#ifdef HAS_UPD4990A\r
-                               }\r
-#endif\r
-                               shift_data >>= 1;\r
-                               if(din) {\r
-                                       shift_data |= bit;\r
-                               } else {\r
-                                       shift_data &= ~bit;\r
-                               }\r
-                               // output LSB\r
-                               dout = (uint32)(shift_data & 1);\r
-                               dout_changed = true;\r
-                               write_signals(&outputs_dout, (shift_data & 1) ? 0xffffffff : 0);\r
-                       }\r
-#ifdef HAS_UPD4990A\r
-                       shift_cmd = (shift_cmd >> 1) | (din ? 8 : 0);\r
-#endif\r
-               }\r
-               clk = next;\r
-       } else if(id == SIG_UPD1990A_STB) {\r
-               bool next = ((data & mask) != 0);\r
-               if(!stb && next && !clk) {\r
-#ifdef HAS_UPD4990A\r
-                       if(cmd == 7) {\r
-                               mode = shift_cmd | 0x80;\r
-                       } else {\r
-#endif\r
-                               mode = cmd;\r
-#ifdef HAS_UPD4990A\r
-                       }\r
-#endif\r
-                       switch(mode & 0x0f) {\r
-                       case 0x02:\r
-                               {\r
-                                       uint64 tmp = shift_data;\r
-                                       cur_time.second = FROM_BCD(tmp);\r
-                                       tmp >>= 8;\r
-                                       cur_time.minute = FROM_BCD(tmp);\r
-                                       tmp >>= 8;\r
-                                       cur_time.hour = FROM_BCD(tmp);\r
-                                       tmp >>= 8;\r
-                                       cur_time.day = FROM_BCD(tmp);\r
-                                       tmp >>= 8;\r
-                                       cur_time.day_of_week = tmp & 0x0f;\r
-                                       tmp >>= 4;\r
-                                       cur_time.month = tmp & 0x0f;\r
-#ifdef HAS_UPD4990A\r
-                                       if(mode & 0x80) {\r
-                                               tmp >>= 4;\r
-                                               cur_time.year = FROM_BCD(tmp);\r
-                                               cur_time.update_year();\r
-                                               cur_time.update_day_of_week();\r
-                                       }\r
-#endif\r
-                               }\r
-                               hold = true;\r
-                               break;\r
-                       case 0x03:\r
-                               // after all bits are read, lsb of second data can be read\r
-                               shift_data = TO_BCD(cur_time.second);\r
-                               //shift_data = 0;\r
-#ifdef HAS_UPD4990A\r
-                               if(mode & 0x80) {\r
-                                       shift_data <<= 8;\r
-                                       shift_data |= TO_BCD(cur_time.year);\r
-                               }\r
-#endif\r
-                               shift_data <<= 4;\r
-                               shift_data |= cur_time.month;\r
-                               shift_data <<= 4;\r
-                               shift_data |= cur_time.day_of_week;\r
-                               shift_data <<= 8;\r
-                               shift_data |= TO_BCD(cur_time.day);\r
-                               shift_data <<= 8;\r
-                               shift_data |= TO_BCD(cur_time.hour);\r
-                               shift_data <<= 8;\r
-                               shift_data |= TO_BCD(cur_time.minute);\r
-                               shift_data <<= 8;\r
-                               shift_data |= TO_BCD(cur_time.second);\r
-                               // output LSB\r
-                               dout = (uint32)(shift_data & 1);\r
-                               dout_changed = true;\r
-                               write_signals(&outputs_dout, (shift_data & 1) ? 0xffffffff : 0);\r
-                               break;\r
-                       case 0x04:\r
-                       case 0x05:\r
-                       case 0x06:\r
-#ifdef HAS_UPD4990A\r
-                       case 0x07:\r
-                       case 0x08:\r
-                       case 0x09:\r
-                       case 0x0a:\r
-                       case 0x0b:\r
-#endif\r
-                               if(tpmode != (mode & 0x0f)) {\r
-                                       if(outputs_tp.count != 0) {\r
-                                               static const double tbl[] = {\r
-                                                       1000000.0 / 128.0,      // 64Hz\r
-                                                       1000000.0 / 512.0,      // 256Hz\r
-                                                       1000000.0 / 2048.0,     // 2048Hz\r
-#ifdef HAS_UPD4990A\r
-                                                       1000000.0 / 4098.0,     // 4096Hz\r
-                                                       1000000.0,              // 1sec\r
-                                                       1000000.0 * 10,         // 10sec\r
-                                                       1000000.0 * 30,         // 30sec\r
-                                                       1000000.0 * 60          // 60sec\r
-#endif\r
-                                               };\r
-                                               if(register_id_tp != -1) {\r
-                                                       cancel_event(this, register_id_tp);\r
-                                                       register_id_tp = -1;\r
-                                               }\r
-                                               register_event(this, EVENT_TP, tbl[(mode & 0x0f) - 4], true, &register_id_tp);\r
-                                       }\r
-                                       tpmode = mode & 0x0f;\r
-                               }\r
-                               break;\r
-                       }\r
-                       // reset counter hold\r
-                       switch(mode & 0x0f) {\r
-                       case 0x00:\r
-                       case 0x01:\r
-                       case 0x03:\r
-                               if(hold) {\r
-                                       // restart event\r
-                                       cancel_event(this, register_id_1sec);\r
-                                       register_event(this, EVENT_1SEC, 1000000.0, true, &register_id_1sec);\r
-                                       hold = false;\r
-                               }\r
-                               break;\r
-                       }\r
-               }\r
-               stb = next;\r
-       } else if(id == SIG_UPD1990A_CMD) {\r
-               cmd = (cmd & ~mask) | (data & mask);\r
-               cmd &= 7;\r
-       } else if(id == SIG_UPD1990A_C0) {\r
-               cmd = (cmd & ~1) | (data & mask ? 1 : 0);\r
-               cmd &= 7;\r
-       } else if(id == SIG_UPD1990A_C1) {\r
-               cmd = (cmd & ~2) | (data & mask ? 2 : 0);\r
-               cmd &= 7;\r
-       } else if(id == SIG_UPD1990A_C2) {\r
-               cmd = (cmd & ~4) | (data & mask ? 4 : 0);\r
-               cmd &= 7;\r
-       } else if(id == SIG_UPD1990A_DIN) {\r
-               din = ((data & mask) != 0);\r
-       }\r
-}\r
-\r
-void UPD1990A::event_callback(int event_id, int err)\r
-{\r
-       if(event_id == EVENT_1SEC) {\r
-               if(cur_time.initialized) {\r
-                       if(!hold) {\r
-                               cur_time.increment();\r
-                       }\r
-                       if(dout_changed) {\r
-                               dout_changed = false;\r
-                       } else {\r
-                               dout = cur_time.second & 1;\r
-                               write_signals(&outputs_dout, (cur_time.second & 1) ? 0xffffffff : 0);\r
-                       }\r
-               } else {\r
-                       emu->get_host_time(&cur_time);  // resync\r
-                       cur_time.initialized = true;\r
-               }\r
-       } else if(event_id == EVENT_TP) {\r
-               write_signals(&outputs_tp, tp ? 0xffffffff : 0);\r
-               tp = !tp;\r
-       }\r
-}\r
-\r
-#define STATE_VERSION  2\r
-\r
-void UPD1990A::save_state(FILEIO* state_fio)\r
-{\r
-       state_fio->FputUint32(STATE_VERSION);\r
-       state_fio->FputInt32(this_device_id);\r
-       \r
-       cur_time.save_state((void *)state_fio);\r
-       state_fio->FputInt32(register_id_1sec);\r
-       state_fio->FputUint8(cmd);\r
-       state_fio->FputUint8(mode);\r
-       state_fio->FputUint8(tpmode);\r
-       state_fio->FputUint64(shift_data);\r
-       state_fio->FputBool(clk);\r
-       state_fio->FputBool(stb);\r
-       state_fio->FputBool(din);\r
-       state_fio->FputBool(hold);\r
-       state_fio->FputBool(tp);\r
-       state_fio->FputUint32(dout);\r
-       state_fio->FputBool(dout_changed);\r
-       state_fio->FputInt32(register_id_tp);\r
-#ifdef HAS_UPD4990A\r
-       state_fio->FputUint8(shift_cmd);\r
-#endif\r
-}\r
-\r
-bool UPD1990A::load_state(FILEIO* state_fio)\r
-{\r
-       if(state_fio->FgetUint32() != STATE_VERSION) {\r
-               return false;\r
-       }\r
-       if(state_fio->FgetInt32() != this_device_id) {\r
-               return false;\r
-       }\r
-       if(!cur_time.load_state((void *)state_fio)) {\r
-               return false;\r
-       }\r
-       register_id_1sec = state_fio->FgetInt32();\r
-       cmd = state_fio->FgetUint8();\r
-       mode = state_fio->FgetUint8();\r
-       tpmode = state_fio->FgetUint8();\r
-       shift_data = state_fio->FgetUint64();\r
-       clk = state_fio->FgetBool();\r
-       stb = state_fio->FgetBool();\r
-       din = state_fio->FgetBool();\r
-       hold = state_fio->FgetBool();\r
-       tp = state_fio->FgetBool();\r
-       dout = state_fio->FgetUint32();\r
-       dout_changed = state_fio->FgetBool();\r
-       register_id_tp = state_fio->FgetInt32();\r
-#ifdef HAS_UPD4990A\r
-       shift_cmd = state_fio->FgetUint8();\r
-#endif\r
-       return true;\r
-}\r
-\r
+/*
+       Skelton for retropc emulator
+
+       Author : Takeda.Toshiya
+       Date   : 2008.04.19-
+
+       [ uPD1990A / uPD4990A ]
+*/
+
+#include "upd1990a.h"
+
+#define EVENT_1SEC     0
+#define EVENT_TP       1
+
+void UPD1990A::initialize()
+{
+       // initialize rtc
+       get_host_time(&cur_time);
+       
+       // register events
+       register_event(this, EVENT_1SEC, 1000000.0, true, &register_id_1sec);
+       register_id_tp = -1;
+}
+
+void UPD1990A::write_signal(int id, uint32 data, uint32 mask)
+{
+       if(id == SIG_UPD1990A_CLK) {
+               bool next = ((data & mask) != 0);
+               if(!clk && next) {
+                       if((mode & 0x0f) == 1) {
+                               uint64 bit = 1;
+#ifdef HAS_UPD4990A
+                               if(mode & 0x80) {
+                                       bit <<= (52 - 1);
+                               } else {
+#endif
+                                       bit <<= (40 - 1);
+#ifdef HAS_UPD4990A
+                               }
+#endif
+                               shift_data >>= 1;
+                               if(din) {
+                                       shift_data |= bit;
+                               } else {
+                                       shift_data &= ~bit;
+                               }
+                               // output LSB
+                               dout = (uint32)(shift_data & 1);
+                               dout_changed = true;
+                               write_signals(&outputs_dout, (shift_data & 1) ? 0xffffffff : 0);
+                       }
+#ifdef HAS_UPD4990A
+                       shift_cmd = (shift_cmd >> 1) | (din ? 8 : 0);
+#endif
+               }
+               clk = next;
+       } else if(id == SIG_UPD1990A_STB) {
+               bool next = ((data & mask) != 0);
+               if(!stb && next && !clk) {
+#ifdef HAS_UPD4990A
+                       if(cmd == 7) {
+                               mode = shift_cmd | 0x80;
+                       } else {
+#endif
+                               mode = cmd;
+#ifdef HAS_UPD4990A
+                       }
+#endif
+                       switch(mode & 0x0f) {
+                       case 0x02:
+                               {
+                                       uint64 tmp = shift_data;
+                                       cur_time.second = FROM_BCD(tmp);
+                                       tmp >>= 8;
+                                       cur_time.minute = FROM_BCD(tmp);
+                                       tmp >>= 8;
+                                       cur_time.hour = FROM_BCD(tmp);
+                                       tmp >>= 8;
+                                       cur_time.day = FROM_BCD(tmp);
+                                       tmp >>= 8;
+                                       cur_time.day_of_week = tmp & 0x0f;
+                                       tmp >>= 4;
+                                       cur_time.month = tmp & 0x0f;
+#ifdef HAS_UPD4990A
+                                       if(mode & 0x80) {
+                                               tmp >>= 4;
+                                               cur_time.year = FROM_BCD(tmp);
+                                               cur_time.update_year();
+                                               cur_time.update_day_of_week();
+                                       }
+#endif
+                               }
+                               hold = true;
+                               break;
+                       case 0x03:
+                               // after all bits are read, lsb of second data can be read
+                               shift_data = TO_BCD(cur_time.second);
+                               //shift_data = 0;
+#ifdef HAS_UPD4990A
+                               if(mode & 0x80) {
+                                       shift_data <<= 8;
+                                       shift_data |= TO_BCD(cur_time.year);
+                               }
+#endif
+                               shift_data <<= 4;
+                               shift_data |= cur_time.month;
+                               shift_data <<= 4;
+                               shift_data |= cur_time.day_of_week;
+                               shift_data <<= 8;
+                               shift_data |= TO_BCD(cur_time.day);
+                               shift_data <<= 8;
+                               shift_data |= TO_BCD(cur_time.hour);
+                               shift_data <<= 8;
+                               shift_data |= TO_BCD(cur_time.minute);
+                               shift_data <<= 8;
+                               shift_data |= TO_BCD(cur_time.second);
+                               // output LSB
+                               dout = (uint32)(shift_data & 1);
+                               dout_changed = true;
+                               write_signals(&outputs_dout, (shift_data & 1) ? 0xffffffff : 0);
+                               break;
+                       case 0x04:
+                       case 0x05:
+                       case 0x06:
+#ifdef HAS_UPD4990A
+                       case 0x07:
+                       case 0x08:
+                       case 0x09:
+                       case 0x0a:
+                       case 0x0b:
+#endif
+                               if(tpmode != (mode & 0x0f)) {
+                                       if(outputs_tp.count != 0) {
+                                               static const double tbl[] = {
+                                                       1000000.0 / 128.0,      // 64Hz
+                                                       1000000.0 / 512.0,      // 256Hz
+                                                       1000000.0 / 2048.0,     // 2048Hz
+#ifdef HAS_UPD4990A
+                                                       1000000.0 / 4098.0,     // 4096Hz
+                                                       1000000.0,              // 1sec
+                                                       1000000.0 * 10,         // 10sec
+                                                       1000000.0 * 30,         // 30sec
+                                                       1000000.0 * 60          // 60sec
+#endif
+                                               };
+                                               if(register_id_tp != -1) {
+                                                       cancel_event(this, register_id_tp);
+                                                       register_id_tp = -1;
+                                               }
+                                               register_event(this, EVENT_TP, tbl[(mode & 0x0f) - 4], true, &register_id_tp);
+                                       }
+                                       tpmode = mode & 0x0f;
+                               }
+                               break;
+                       }
+                       // reset counter hold
+                       switch(mode & 0x0f) {
+                       case 0x00:
+                       case 0x01:
+                       case 0x03:
+                               if(hold) {
+                                       // restart event
+                                       cancel_event(this, register_id_1sec);
+                                       register_event(this, EVENT_1SEC, 1000000.0, true, &register_id_1sec);
+                                       hold = false;
+                               }
+                               break;
+                       }
+               }
+               stb = next;
+       } else if(id == SIG_UPD1990A_CMD) {
+               cmd = (cmd & ~mask) | (data & mask);
+               cmd &= 7;
+       } else if(id == SIG_UPD1990A_C0) {
+               cmd = (cmd & ~1) | (data & mask ? 1 : 0);
+               cmd &= 7;
+       } else if(id == SIG_UPD1990A_C1) {
+               cmd = (cmd & ~2) | (data & mask ? 2 : 0);
+               cmd &= 7;
+       } else if(id == SIG_UPD1990A_C2) {
+               cmd = (cmd & ~4) | (data & mask ? 4 : 0);
+               cmd &= 7;
+       } else if(id == SIG_UPD1990A_DIN) {
+               din = ((data & mask) != 0);
+       }
+}
+
+void UPD1990A::event_callback(int event_id, int err)
+{
+       if(event_id == EVENT_1SEC) {
+               if(cur_time.initialized) {
+                       if(!hold) {
+                               cur_time.increment();
+                       }
+                       if(dout_changed) {
+                               dout_changed = false;
+                       } else {
+                               dout = cur_time.second & 1;
+                               write_signals(&outputs_dout, (cur_time.second & 1) ? 0xffffffff : 0);
+                       }
+               } else {
+                       get_host_time(&cur_time);       // resync
+                       cur_time.initialized = true;
+               }
+       } else if(event_id == EVENT_TP) {
+               write_signals(&outputs_tp, tp ? 0xffffffff : 0);
+               tp = !tp;
+       }
+}
+
+#define STATE_VERSION  2
+
+void UPD1990A::save_state(FILEIO* state_fio)
+{
+       state_fio->FputUint32(STATE_VERSION);
+       state_fio->FputInt32(this_device_id);
+       
+       cur_time.save_state((void *)state_fio);
+       state_fio->FputInt32(register_id_1sec);
+       state_fio->FputUint8(cmd);
+       state_fio->FputUint8(mode);
+       state_fio->FputUint8(tpmode);
+       state_fio->FputUint64(shift_data);
+       state_fio->FputBool(clk);
+       state_fio->FputBool(stb);
+       state_fio->FputBool(din);
+       state_fio->FputBool(hold);
+       state_fio->FputBool(tp);
+       state_fio->FputUint32(dout);
+       state_fio->FputBool(dout_changed);
+       state_fio->FputInt32(register_id_tp);
+#ifdef HAS_UPD4990A
+       state_fio->FputUint8(shift_cmd);
+#endif
+}
+
+bool UPD1990A::load_state(FILEIO* state_fio)
+{
+       if(state_fio->FgetUint32() != STATE_VERSION) {
+               return false;
+       }
+       if(state_fio->FgetInt32() != this_device_id) {
+               return false;
+       }
+       if(!cur_time.load_state((void *)state_fio)) {
+               return false;
+       }
+       register_id_1sec = state_fio->FgetInt32();
+       cmd = state_fio->FgetUint8();
+       mode = state_fio->FgetUint8();
+       tpmode = state_fio->FgetUint8();
+       shift_data = state_fio->FgetUint64();
+       clk = state_fio->FgetBool();
+       stb = state_fio->FgetBool();
+       din = state_fio->FgetBool();
+       hold = state_fio->FgetBool();
+       tp = state_fio->FgetBool();
+       dout = state_fio->FgetUint32();
+       dout_changed = state_fio->FgetBool();
+       register_id_tp = state_fio->FgetInt32();
+#ifdef HAS_UPD4990A
+       shift_cmd = state_fio->FgetUint8();
+#endif
+       return true;
+}
+