OSDN Git Service

[General] Convert sourcecode's CRLF format: DOS(WINDOWS) to Unix, to apply patches...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr30 / rtc.cpp
index 7570d1d..0e52a96 100644 (file)
-/*\r
-       FUJITSU FMR-30 Emulator 'eFMR-30'\r
-\r
-       Author : Takeda.Toshiya\r
-       Date   : 2008.12.30 -\r
-\r
-       [ rtc ]\r
-*/\r
-\r
-#include "rtc.h"\r
-#include "../i8259.h"\r
-#include "../../fileio.h"\r
-\r
-#define EVENT_1HZ      0\r
-#define EVENT_32HZ     1\r
-#define EVENT_DONE     2\r
-\r
-#define POWON  8\r
-#define TCNT   34\r
-#define CKHM   35\r
-#define CKL    36\r
-#define POWOF  36\r
-#define POFMI  37\r
-#define POFH   38\r
-#define POFD   39\r
-\r
-void RTC::initialize()\r
-{\r
-       // load rtc regs image\r
-       memset(regs, 0, sizeof(regs));\r
-       regs[POWON] = 0x10;     // cleared\r
-       \r
-       FILEIO* fio = new FILEIO();\r
-       if(fio->Fopen(emu->bios_path(_T("RTC.BIN")), FILEIO_READ_BINARY)) {\r
-               fio->Fread(regs + 8, 32, 1);\r
-               fio->Fclose();\r
-       }\r
-       delete fio;\r
-       \r
-       // init registers\r
-//     regs[POWON] &= 0x1f;    // local power on\r
-//     regs[POWOF] = 0x80;     // program power off\r
-       regs[POWON] = 0x10;     // cleared\r
-       regs[POWOF] = 0x20;     // illegal power off\r
-       regs[TCNT] = 0;\r
-       update_checksum();\r
-       \r
-       rtcmr = rtdsr = 0;\r
-       \r
-       // update calendar\r
-       emu->get_host_time(&cur_time);\r
-       read_from_cur_time();\r
-       \r
-       // register event\r
-       register_event_by_clock(this, EVENT_1HZ, CPU_CLOCKS, true, &register_id);\r
-       register_event_by_clock(this, EVENT_32HZ, CPU_CLOCKS >> 5, true, NULL);\r
-}\r
-\r
-void RTC::release()\r
-{\r
-       // set power off time\r
-       regs[POFMI] = TO_BCD(cur_time.minute);\r
-       regs[POFH] = TO_BCD(cur_time.hour);\r
-       regs[POFD] = TO_BCD(cur_time.day);\r
-       \r
-       // save rtc regs image\r
-       FILEIO* fio = new FILEIO();\r
-       if(fio->Fopen(emu->bios_path(_T("RTC.BIN")), FILEIO_WRITE_BINARY)) {\r
-               fio->Fwrite(regs + 8, 32, 1);\r
-               fio->Fclose();\r
-       }\r
-       delete fio;\r
-}\r
-\r
-void RTC::write_io16(uint32 addr, uint32 data)\r
-{\r
-       switch(addr) {\r
-       case 0:\r
-               rtcmr = data;\r
-               break;\r
-       case 2:\r
-               // echo reset\r
-               rtdsr &= ~(data & 0xe);\r
-               update_intr();\r
-               break;\r
-       case 4:\r
-               if(!(rtdsr & 1)) {\r
-                       rtadr = data;\r
-                       rtdsr |= 1;\r
-                       // register event\r
-                       register_event(this, EVENT_DONE, 100, false, NULL);\r
-               }\r
-               break;\r
-       case 6:\r
-               rtobr = data;\r
-               break;\r
-       }\r
-}\r
-\r
-uint32 RTC::read_io16(uint32 addr)\r
-{\r
-       switch(addr) {\r
-       case 2:\r
-               return rtdsr;\r
-       case 6:\r
-               return rtibr;\r
-       }\r
-       return 0xffff;\r
-}\r
-\r
-void RTC::event_callback(int event_id, int err)\r
-{\r
-       if(event_id == EVENT_1HZ) {\r
-               // update calendar\r
-               if(cur_time.initialized) {\r
-                       cur_time.increment();\r
-               } else {\r
-                       emu->get_host_time(&cur_time);  // resync\r
-                       cur_time.initialized = true;\r
-               }\r
-               read_from_cur_time();\r
-               \r
-               // 1sec interrupt\r
-               rtdsr |= 4;\r
-               update_intr();\r
-       } else if(event_id == EVENT_32HZ) {\r
-               // update tcnt\r
-               regs[TCNT]++;\r
-       } else if(event_id == EVENT_DONE) {\r
-               int ch = (rtadr >> 1) & 0x3f;\r
-               if(rtadr & 1) {\r
-                       // invalid address\r
-               } else if(rtadr & 0x80) {\r
-                       // write\r
-                       if(ch <= 6) {\r
-                               regs[ch] = (uint8)rtobr;\r
-                               write_to_cur_time();\r
-                       } else if(ch == POWON) {\r
-                               regs[ch] = (regs[ch] & 0xe0) | (rtobr & 0x1f);\r
-                               if((rtobr & 0xe0) == 0xc0) {\r
-                                       // reipl\r
-                                       regs[ch] = (regs[ch] & 0x1f) | 0xc0;\r
-                                       vm->reset();\r
-                               } else if((rtobr & 0xe0) == 0xe0) {\r
-                                       // power off\r
-                                       emu->power_off();\r
-                               }\r
-                               update_checksum();\r
-                       } else if(7 <= ch && ch < 32) {\r
-                               regs[ch] = (uint8)rtobr;\r
-                               update_checksum();\r
-                       }\r
-               } else {\r
-                       // read\r
-                       if(ch < 40) {\r
-                               rtibr = regs[ch];\r
-                       }\r
-               }\r
-               // update flags\r
-               rtdsr &= ~1;\r
-               rtdsr |= 2;\r
-               update_intr();\r
-       }\r
-}\r
-\r
-void RTC::read_from_cur_time()\r
-{\r
-       regs[0] = TO_BCD(cur_time.second);\r
-       regs[1] = TO_BCD(cur_time.minute);\r
-       regs[2] = TO_BCD(cur_time.hour);\r
-       regs[3] = cur_time.day_of_week;\r
-       regs[4] = TO_BCD(cur_time.day);\r
-       regs[5] = TO_BCD(cur_time.month);\r
-       regs[6] = TO_BCD(cur_time.year);\r
-}\r
-\r
-void RTC::write_to_cur_time()\r
-{\r
-       cur_time.second = FROM_BCD(regs[0]);\r
-       cur_time.minute = FROM_BCD(regs[1]);\r
-       cur_time.hour = FROM_BCD(regs[2]);\r
-//     cur_time.day_of_week = regs[3];\r
-       cur_time.day = FROM_BCD(regs[4]);\r
-       cur_time.month = FROM_BCD(regs[5]);\r
-       cur_time.year = FROM_BCD(regs[6]);\r
-       cur_time.update_year();\r
-       cur_time.update_day_of_week();\r
-       \r
-       // restart event\r
-       cancel_event(this, register_id);\r
-       register_event_by_clock(this, EVENT_1HZ, CPU_CLOCKS, true, &register_id);\r
-}\r
-\r
-void RTC::update_checksum()\r
-{\r
-       int sum = 0;\r
-       for(int i = 8; i < 32; i++) {\r
-               sum += regs[i] & 0xf;\r
-               sum += (regs[i] >> 4) & 0xf;\r
-       }\r
-       uint8 ckh = (sum >> 6) & 0xf;\r
-       uint8 ckm = (sum >> 2) & 0xf;\r
-       uint8 ckl = (sum >> 0) & 3;\r
-       \r
-       regs[CKHM] = ckh | (ckm << 4);\r
-       regs[CKL] = (regs[CKL] & 0xf0) | ckl | 0xc;\r
-}\r
-\r
-void RTC::update_intr()\r
-{\r
-       d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, (rtcmr & rtdsr & 0xe) ? 1 : 0, 1);\r
-}\r
+/*
+       FUJITSU FMR-30 Emulator 'eFMR-30'
+
+       Author : Takeda.Toshiya
+       Date   : 2008.12.30 -
+
+       [ rtc ]
+*/
+
+#include "rtc.h"
+#include "../i8259.h"
+#include "../../fileio.h"
+
+#define EVENT_1HZ      0
+#define EVENT_32HZ     1
+#define EVENT_DONE     2
+
+#define POWON  8
+#define TCNT   34
+#define CKHM   35
+#define CKL    36
+#define POWOF  36
+#define POFMI  37
+#define POFH   38
+#define POFD   39
+
+void RTC::initialize()
+{
+       // load rtc regs image
+       memset(regs, 0, sizeof(regs));
+       regs[POWON] = 0x10;     // cleared
+       
+       FILEIO* fio = new FILEIO();
+       if(fio->Fopen(emu->bios_path(_T("RTC.BIN")), FILEIO_READ_BINARY)) {
+               fio->Fread(regs + 8, 32, 1);
+               fio->Fclose();
+       }
+       delete fio;
+       
+       // init registers
+//     regs[POWON] &= 0x1f;    // local power on
+//     regs[POWOF] = 0x80;     // program power off
+       regs[POWON] = 0x10;     // cleared
+       regs[POWOF] = 0x20;     // illegal power off
+       regs[TCNT] = 0;
+       update_checksum();
+       
+       rtcmr = rtdsr = 0;
+       
+       // update calendar
+       emu->get_host_time(&cur_time);
+       read_from_cur_time();
+       
+       // register event
+       register_event_by_clock(this, EVENT_1HZ, CPU_CLOCKS, true, &register_id);
+       register_event_by_clock(this, EVENT_32HZ, CPU_CLOCKS >> 5, true, NULL);
+}
+
+void RTC::release()
+{
+       // set power off time
+       regs[POFMI] = TO_BCD(cur_time.minute);
+       regs[POFH] = TO_BCD(cur_time.hour);
+       regs[POFD] = TO_BCD(cur_time.day);
+       
+       // save rtc regs image
+       FILEIO* fio = new FILEIO();
+       if(fio->Fopen(emu->bios_path(_T("RTC.BIN")), FILEIO_WRITE_BINARY)) {
+               fio->Fwrite(regs + 8, 32, 1);
+               fio->Fclose();
+       }
+       delete fio;
+}
+
+void RTC::write_io16(uint32 addr, uint32 data)
+{
+       switch(addr) {
+       case 0:
+               rtcmr = data;
+               break;
+       case 2:
+               // echo reset
+               rtdsr &= ~(data & 0xe);
+               update_intr();
+               break;
+       case 4:
+               if(!(rtdsr & 1)) {
+                       rtadr = data;
+                       rtdsr |= 1;
+                       // register event
+                       register_event(this, EVENT_DONE, 100, false, NULL);
+               }
+               break;
+       case 6:
+               rtobr = data;
+               break;
+       }
+}
+
+uint32 RTC::read_io16(uint32 addr)
+{
+       switch(addr) {
+       case 2:
+               return rtdsr;
+       case 6:
+               return rtibr;
+       }
+       return 0xffff;
+}
+
+void RTC::event_callback(int event_id, int err)
+{
+       if(event_id == EVENT_1HZ) {
+               // update calendar
+               if(cur_time.initialized) {
+                       cur_time.increment();
+               } else {
+                       emu->get_host_time(&cur_time);  // resync
+                       cur_time.initialized = true;
+               }
+               read_from_cur_time();
+               
+               // 1sec interrupt
+               rtdsr |= 4;
+               update_intr();
+       } else if(event_id == EVENT_32HZ) {
+               // update tcnt
+               regs[TCNT]++;
+       } else if(event_id == EVENT_DONE) {
+               int ch = (rtadr >> 1) & 0x3f;
+               if(rtadr & 1) {
+                       // invalid address
+               } else if(rtadr & 0x80) {
+                       // write
+                       if(ch <= 6) {
+                               regs[ch] = (uint8)rtobr;
+                               write_to_cur_time();
+                       } else if(ch == POWON) {
+                               regs[ch] = (regs[ch] & 0xe0) | (rtobr & 0x1f);
+                               if((rtobr & 0xe0) == 0xc0) {
+                                       // reipl
+                                       regs[ch] = (regs[ch] & 0x1f) | 0xc0;
+                                       vm->reset();
+                               } else if((rtobr & 0xe0) == 0xe0) {
+                                       // power off
+                                       emu->power_off();
+                               }
+                               update_checksum();
+                       } else if(7 <= ch && ch < 32) {
+                               regs[ch] = (uint8)rtobr;
+                               update_checksum();
+                       }
+               } else {
+                       // read
+                       if(ch < 40) {
+                               rtibr = regs[ch];
+                       }
+               }
+               // update flags
+               rtdsr &= ~1;
+               rtdsr |= 2;
+               update_intr();
+       }
+}
+
+void RTC::read_from_cur_time()
+{
+       regs[0] = TO_BCD(cur_time.second);
+       regs[1] = TO_BCD(cur_time.minute);
+       regs[2] = TO_BCD(cur_time.hour);
+       regs[3] = cur_time.day_of_week;
+       regs[4] = TO_BCD(cur_time.day);
+       regs[5] = TO_BCD(cur_time.month);
+       regs[6] = TO_BCD(cur_time.year);
+}
+
+void RTC::write_to_cur_time()
+{
+       cur_time.second = FROM_BCD(regs[0]);
+       cur_time.minute = FROM_BCD(regs[1]);
+       cur_time.hour = FROM_BCD(regs[2]);
+//     cur_time.day_of_week = regs[3];
+       cur_time.day = FROM_BCD(regs[4]);
+       cur_time.month = FROM_BCD(regs[5]);
+       cur_time.year = FROM_BCD(regs[6]);
+       cur_time.update_year();
+       cur_time.update_day_of_week();
+       
+       // restart event
+       cancel_event(this, register_id);
+       register_event_by_clock(this, EVENT_1HZ, CPU_CLOCKS, true, &register_id);
+}
+
+void RTC::update_checksum()
+{
+       int sum = 0;
+       for(int i = 8; i < 32; i++) {
+               sum += regs[i] & 0xf;
+               sum += (regs[i] >> 4) & 0xf;
+       }
+       uint8 ckh = (sum >> 6) & 0xf;
+       uint8 ckm = (sum >> 2) & 0xf;
+       uint8 ckl = (sum >> 0) & 3;
+       
+       regs[CKHM] = ckh | (ckm << 4);
+       regs[CKL] = (regs[CKL] & 0xf0) | ckl | 0xc;
+}
+
+void RTC::update_intr()
+{
+       d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, (rtcmr & rtdsr & 0xe) ? 1 : 0, 1);
+}