summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/aicartc.cpp
blob: c6d5beb5a45099b6c1b40ee107092e5c5fd71ee2 (plain) (tree)
1
2
3
4
5
6
7
8

                                  

                                                                            
                       
 

                                                                  












                                                                            
                                                                  









                                                                            
                                                                                                               



                                                                  




















                                                                                         





                                                   
 




                                                                                                                       
                                       


                                    
 

                                       
 
















                                                                                                                                              




































                                                                                             
                     








































                                                                                      
// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/***************************************************************************

    AICA-RTC sub-device

    TODO:
    - move this inside AICA sound core once that'll get modernized

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

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



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

// device type definition
DEFINE_DEVICE_TYPE(AICARTC, aicartc_device, "aicartc", "AICA RTC")


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

//-------------------------------------------------
//  aicartc_device - constructor
//-------------------------------------------------

aicartc_device::aicartc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, AICARTC, tag, owner, clock)
	, device_rtc_interface(mconfig, *this)
	, m_rtc_reg_lo(0), m_rtc_reg_hi(0), m_rtc_tick(0), m_we(0)
	, m_clock_timer(nullptr)
{
}


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

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

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

void aicartc_device::device_start()
{
	m_clock_timer = timer_alloc();
	m_clock_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
}


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

void aicartc_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
{
	const int month_to_day_conversion[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };

	// put the seconds
	uint32_t current_time = second;

	// put the minutes
	current_time += minute * 60;

	// put the hours
	current_time += hour * 60 * 60;

	// put the days (note -1) */
	current_time += (day - 1) * 60 * 60 * 24;

	// take the months - despite popular beliefs, leap years aren't just evenly divisible by 4 */
	if (((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0)) && month > 2)
		current_time += (month_to_day_conversion[month - 1] + 1) * 60 * 60 * 24;
	else
		current_time += (month_to_day_conversion[month - 1]) * 60 * 60 * 24;

	// put the years
	int year_count = (year - 1949);

	for (int i = 0; i < year_count - 1; i++)
		current_time += (((((i+1950) % 4) == 0) && (((i+1950) % 100) != 0)) || (((i+1950) % 400) == 0)) ? 60*60*24*366 : 60*60*24*365;

	m_rtc_reg_lo = current_time & 0x0000ffff;
	m_rtc_reg_hi = (current_time & 0xffff0000) >> 16;
}


//-------------------------------------------------
//  device_reset - device-specific reset
//-------------------------------------------------

void aicartc_device::device_reset()
{
	m_rtc_tick = 0;
}


//-------------------------------------------------
//  device_timer - handler timer events
//-------------------------------------------------


void aicartc_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	m_rtc_tick++;
	if(m_rtc_tick & 0x8000)
	{
		m_rtc_tick = 0;
		m_rtc_reg_lo++;
		if(m_rtc_reg_lo == 0)
			m_rtc_reg_hi++;
	}
}


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

READ16_MEMBER( aicartc_device::read )
{
	uint16_t res;

	res = 0;
	switch(offset)
	{
		case 0:
			res = m_rtc_reg_hi; break;
		case 1:
			res = m_rtc_reg_lo; break;
	}

	return res;
}

WRITE16_MEMBER( aicartc_device::write )
{
	switch(offset)
	{
		case 0:
			if(m_we)
			{
				COMBINE_DATA(&m_rtc_reg_hi);
				// clear write enable here?
			}

			break;

		case 1:
			if(m_we)
			{
				COMBINE_DATA(&m_rtc_reg_lo);
				m_rtc_tick = 0; // low register also clears tick count
			}

			break;

		case 2:
			m_we = data & 1;
			break;
	}

}