summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/upd4992.cpp
blob: a6c81fb9d13c56033811df1fc2eacc7eea60c70d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// license:BSD-3-Clause
// copyright-holders: Angelo Salese
/***************************************************************************

    uPD4992 parallel RTC

    TODO:
    - Add timers
    - Add leap year count
    - Add 12 hours mode
    - Add mode/control register

***************************************************************************/

#include "emu.h"
#include "machine/upd4992.h"



//**************************************************************************
//  GLOBAL VARIABLES
//**************************************************************************

// device type definition
DEFINE_DEVICE_TYPE(UPD4992, upd4992_device, "upd4992", "uPD4992 RTC")


//**************************************************************************
//  LIVE DEVICE
//**************************************************************************

//-------------------------------------------------
//  upd4992_device - constructor
//-------------------------------------------------

upd4992_device::upd4992_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, UPD4992, tag, owner, clock)
	, device_rtc_interface(mconfig, *this)
	, m_timer_clock(nullptr)
{
}


//-------------------------------------------------
//  device_validity_check - perform validity checks
//  on this device
//-------------------------------------------------

void upd4992_device::device_validity_check(validity_checker &valid) const
{
}


//-------------------------------------------------
//  device_start - device-specific startup
//-------------------------------------------------

void upd4992_device::device_start()
{
	m_timer_clock = timer_alloc(TIMER_CLOCK);
	m_timer_clock->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
}


void upd4992_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch (id)
	{
	case TIMER_CLOCK:
		advance_seconds();
		break;
	}
}

//-------------------------------------------------
//  rtc_clock_updated -
//-------------------------------------------------

void upd4992_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
{
/*
[2]
x--- ---- 12/24H flag
-x-- ---- AM/PM flag
--xx ---- 10 hour digit
---- xxxx 1s hour digit
[3]
xx-- ---- Leap year control
--xx ---- Leap year counter
---- xxxx Day of week digit
[4]
xxxx ---- 10s day digit
---- xxxx 1s day digit
[5]
xxxx ---- 10s month digit
---- xxxx 1s month digit
[6]
xxxx ---- 10s year digit
---- xxxx 1s year digit
[7]
xxxx ---- Mode register
---- xxxx Control Register
*/
	m_rtc_regs[0] = convert_to_bcd(second);
	m_rtc_regs[1] = convert_to_bcd(minute);
	m_rtc_regs[2] = convert_to_bcd(hour);
	m_rtc_regs[3] = day_of_week-1;
	m_rtc_regs[4] = convert_to_bcd(day);
	m_rtc_regs[5] = convert_to_bcd(month);
	m_rtc_regs[6] = convert_to_bcd(year);
}

//**************************************************************************
//  READ/WRITE HANDLERS
//**************************************************************************

READ8_MEMBER( upd4992_device::read )
{
	return m_rtc_regs[offset];
}

WRITE8_MEMBER( upd4992_device::write )
{
	if(offset == 7)
	{
		if(data & 8)
		{
			if(data & 2) // reset
			{
				// ...
			}

			m_timer_clock->enable(data & 1);
		}
	}
	else // TODO: perhaps there's a write inhibit?
	{
		m_rtc_regs[offset] = data;
		set_time(1, bcd_to_integer(m_rtc_regs[6]),
					bcd_to_integer(m_rtc_regs[5]),
					bcd_to_integer(m_rtc_regs[4]),
					m_rtc_regs[3]+1,
					bcd_to_integer(m_rtc_regs[2]),
					bcd_to_integer(m_rtc_regs[1]),
					bcd_to_integer(m_rtc_regs[0]));
	}
}