summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/msm6242.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/msm6242.c')
-rw-r--r--trunk/src/emu/machine/msm6242.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/msm6242.c b/trunk/src/emu/machine/msm6242.c
new file mode 100644
index 00000000000..8ba28098905
--- /dev/null
+++ b/trunk/src/emu/machine/msm6242.c
@@ -0,0 +1,204 @@
+/***************************************************************************
+
+ MSM6242 Real Time Clock
+
+***************************************************************************/
+
+#include "emu.h"
+#include "machine/msm6242.h"
+
+
+enum
+{
+ MSM6242_REG_S1 = 0,
+ MSM6242_REG_S10,
+ MSM6242_REG_MI1,
+ MSM6242_REG_MI10,
+ MSM6242_REG_H1,
+ MSM6242_REG_H10,
+ MSM6242_REG_D1,
+ MSM6242_REG_D10,
+ MSM6242_REG_MO1,
+ MSM6242_REG_MO10,
+ MSM6242_REG_Y1,
+ MSM6242_REG_Y10,
+ MSM6242_REG_W,
+ MSM6242_REG_CD,
+ MSM6242_REG_CE,
+ MSM6242_REG_CF
+};
+
+
+typedef struct _msm6242_t msm6242_t;
+struct _msm6242_t
+{
+ UINT8 reg[3];
+ system_time hold_time;
+};
+
+
+/* makes sure that the passed in device is the right type */
+INLINE msm6242_t *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == MSM6242);
+
+ return (msm6242_t *)downcast<legacy_device_base *>(device)->token();
+}
+
+
+READ8_DEVICE_HANDLER( msm6242_r )
+{
+ system_time curtime, *systime = &curtime;
+ msm6242_t *msm6242 = get_safe_token(device);
+
+ if (msm6242->reg[0] & 1) /* if HOLD is set, use the hold time */
+ {
+ systime = &msm6242->hold_time;
+ }
+ else /* otherwise, use the current time */
+ {
+ device->machine().current_datetime(curtime);
+ }
+
+ switch(offset)
+ {
+ case MSM6242_REG_S1: return systime->local_time.second % 10;
+ case MSM6242_REG_S10: return systime->local_time.second / 10;
+ case MSM6242_REG_MI1: return systime->local_time.minute % 10;
+ case MSM6242_REG_MI10: return systime->local_time.minute / 10;
+ case MSM6242_REG_H1:
+ case MSM6242_REG_H10:
+ {
+ int hour = systime->local_time.hour;
+ int pm = 0;
+
+ /* check for 12/24 hour mode */
+ if ((msm6242->reg[2] & 0x04) == 0) /* 12 hour mode? */
+ {
+ if (hour >= 12)
+ pm = 1;
+
+ hour %= 12;
+
+ if ( hour == 0 )
+ hour = 12;
+ }
+
+ if ( offset == MSM6242_REG_H1 )
+ return hour % 10;
+
+ return (hour / 10) | (pm <<2);
+ }
+
+ case MSM6242_REG_D1: return systime->local_time.mday % 10;
+ case MSM6242_REG_D10: return systime->local_time.mday / 10;
+ case MSM6242_REG_MO1: return (systime->local_time.month+1) % 10;
+ case MSM6242_REG_MO10: return (systime->local_time.month+1) / 10;
+ case MSM6242_REG_Y1: return systime->local_time.year % 10;
+ case MSM6242_REG_Y10: return (systime->local_time.year % 100) / 10;
+ case MSM6242_REG_W: return systime->local_time.weekday;
+ case MSM6242_REG_CD: return msm6242->reg[0];
+ case MSM6242_REG_CE: return msm6242->reg[1];
+ case MSM6242_REG_CF: return msm6242->reg[2];
+ }
+
+ logerror("%s: MSM6242 unmapped offset %02x read\n", device->machine().describe_context(), offset);
+ return 0;
+}
+
+
+WRITE8_DEVICE_HANDLER( msm6242_w )
+{
+ msm6242_t *msm6242 = get_safe_token(device);
+
+ switch(offset)
+ {
+ case MSM6242_REG_CD:
+ {
+ msm6242->reg[0] = data & 0x0f;
+
+ if (data & 1) /* was Hold set? */
+ {
+ device->machine().current_datetime(msm6242->hold_time);
+ }
+
+ return;
+ }
+
+ case MSM6242_REG_CE: msm6242->reg[1] = data & 0x0f; return;
+
+ case MSM6242_REG_CF:
+ {
+ /* the 12/24 mode bit can only be changed while REST is 1 */
+ if ((data ^ msm6242->reg[2]) & 0x04)
+ {
+ msm6242->reg[2] = (msm6242->reg[2] & 0x04) | (data & ~0x04);
+
+ if (msm6242->reg[2] & 1)
+ msm6242->reg[2] = (msm6242->reg[2] & ~0x04) | (data & 0x04);
+ }
+ else
+ {
+ msm6242->reg[2] = data & 0x0f;
+ }
+ return;
+ }
+ }
+
+ logerror("%s: MSM6242 unmapped offset %02x written with %02x\n", device->machine().describe_context(), offset, data);
+}
+
+
+static DEVICE_START( msm6242 )
+{
+ msm6242_t *msm6242 = get_safe_token(device);
+
+ msm6242->reg[0] = 0;
+ msm6242->reg[1] = 0;
+ msm6242->reg[2] = 0;
+ memset(&msm6242->hold_time, 0, sizeof(system_time));
+}
+
+
+DEVICE_GET_INFO( msm6242 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(msm6242_t); break;
+ case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(msm6242); break;
+ case DEVINFO_FCT_STOP: /* Nothing */ break;
+ case DEVINFO_FCT_RESET: /* Nothing */ break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "OKI MSM6242"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "MSM6242 RTC"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.00"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
+ }
+}
+
+
+
+
+
+#if 0
+READ16_HANDLER( msm6242_lsb_r )
+{
+ return msm6242_r(space, offset);
+}
+
+WRITE16_HANDLER( msm6242_lsb_w )
+{
+ if (ACCESSING_BITS_0_7)
+ msm6242_w(space, offset, data);
+}
+#endif
+
+
+DEFINE_LEGACY_DEVICE(MSM6242, msm6242);