summaryrefslogblamecommitdiffstatshomepage
path: root/src/devices/machine/msm5832.cpp
blob: 43bb7b8d299185d7a26045fc83b7025c53edbc66 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12

                               



                                                                       





                                                                       




                             



                    

 


                                                            



























                                                                            

                                                                            























                                                                            








                                                                            
                                                                                                             
                                                                                        





                                                     
 

                                 























                                                                                                         









                                                   

















                                                                                             
                       

                                                   
                                                                                                                       



                                           
                                          






                                                   





                                                   
 





                                                
                                                   
                 
                                                
                 

                    

                                                                                        


                 
                                                                                                            










                                                   
                                                                                                             
 
                            
         






                                                       
 


                                                                                                                                            









                                                   
                                                                                      










                                                   
                                                                             


                  
                                 









                                                   
                                                                           








                                                   
                                                                           










                                                   
                                                                           










                                                   
                                                                         










                                                   
                                                                         


                     
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/**********************************************************************

    OKI MSM5832 Real Time Clock/Calendar emulation

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

/*

    TODO:

    - 12/24 hour
    - AM/PM
    - leap year
    - test input
    - reference signal output

*/

#include "msm5832.h"


// device type definition
const device_type MSM5832 = &device_creator<msm5832_device>;


//**************************************************************************
//  MACROS / CONSTANTS
//**************************************************************************

#define LOG 0


// registers
enum
{
	REGISTER_S1 = 0,
	REGISTER_S10,
	REGISTER_MI1,
	REGISTER_MI10,
	REGISTER_H1,
	REGISTER_H10,
	REGISTER_W,
	REGISTER_D1,
	REGISTER_D10,
	REGISTER_MO1,
	REGISTER_MO10,
	REGISTER_Y1,
	REGISTER_Y10,
	REGISTER_REF = 15
};



//**************************************************************************
//  INLINE HELPERS
//**************************************************************************

//-------------------------------------------------
//  read_counter -
//-------------------------------------------------

inline int msm5832_device::read_counter(int counter)
{
	return (m_reg[counter + 1] * 10) + m_reg[counter];
}


//-------------------------------------------------
//  write_counter -
//-------------------------------------------------

inline void msm5832_device::write_counter(int counter, int value)
{
	m_reg[counter] = value % 10;
	m_reg[counter + 1] = value / 10;
}



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

//-------------------------------------------------
//  msm5832_device - constructor
//-------------------------------------------------

msm5832_device::msm5832_device(const machine_config &mconfig, std::string tag, device_t *owner, UINT32 clock)
	: device_t(mconfig, MSM5832, "MSM5832", tag, owner, clock, "msm5832", __FILE__),
		device_rtc_interface(mconfig, *this),
		m_hold(0),
		m_address(0),
		m_read(0),
		m_write(0),
		m_cs(0)
{
	for (auto & elem : m_reg)
		elem = 0;
}


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

void msm5832_device::device_start()
{
	// allocate timers
	m_clock_timer = timer_alloc(TIMER_CLOCK);
	m_clock_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));

	// state saving
	save_item(NAME(m_reg));
	save_item(NAME(m_hold));
	save_item(NAME(m_address));
	save_item(NAME(m_read));
	save_item(NAME(m_write));
	save_item(NAME(m_cs));
}


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

void msm5832_device::device_reset()
{
	set_current_time(machine());
}


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

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


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

void msm5832_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
{
	write_counter(REGISTER_Y1, year);
	write_counter(REGISTER_MO1, month);
	write_counter(REGISTER_D1, day);
	m_reg[REGISTER_W] = day_of_week-1;
	write_counter(REGISTER_H1, hour);
	write_counter(REGISTER_MI1, minute);
	write_counter(REGISTER_S1, second);
}


//-------------------------------------------------
//  data_r -
//-------------------------------------------------

READ8_MEMBER( msm5832_device::data_r )
{
	UINT8 data = 0;

	if (m_cs && m_read)
	{
		if (m_address == REGISTER_REF)
		{
			// TODO reference output
		}
		else if (m_address <= REGISTER_Y10)
		{
			data = m_reg[m_address];
		}
		else
		{
			// Otrona Attache CP/M BIOS checks unused registers to detect it
			data = 0x0f;
		}
	}

	if (LOG) logerror("MSM5832 '%s' Register Read %01x: %01x\n", tag().c_str(), m_address, data & 0x0f);

	return data & 0x0f;
}


//-------------------------------------------------
//  data_w -
//-------------------------------------------------

WRITE8_MEMBER( msm5832_device::data_w )
{
	if (LOG) logerror("MSM5832 '%s' Register Write %01x: %01x\n", tag().c_str(), m_address, data & 0x0f);

	if (m_cs && m_write)
	{
		if (m_address == REGISTER_REF)
		{
			// TODO reference output
		}
		else if (m_address <= REGISTER_Y10)
		{
			m_reg[m_address] = data & 0x0f;

			set_time(false, read_counter(REGISTER_Y1), read_counter(REGISTER_MO1), read_counter(REGISTER_D1), m_reg[REGISTER_W],
				read_counter(REGISTER_H1), read_counter(REGISTER_MI1), read_counter(REGISTER_S1));
		}
	}
}


//-------------------------------------------------
//  address_w -
//-------------------------------------------------

void msm5832_device::address_w(UINT8 data)
{
	if (LOG) logerror("MSM5832 '%s' Address: %01x\n", tag().c_str(), data & 0x0f);

	m_address = data & 0x0f;
}


//-------------------------------------------------
//  adj_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( msm5832_device::adj_w )
{
	if (LOG) logerror("MSM5832 '%s' 30 ADJ: %u\n", tag().c_str(), state);

	if (state)
	{
		adjust_seconds();
	}
}


//-------------------------------------------------
//  test_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( msm5832_device::test_w )
{
	if (LOG) logerror("MSM5832 '%s' TEST: %u\n", tag().c_str(), state);
}


//-------------------------------------------------
//  hold_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( msm5832_device::hold_w )
{
	if (LOG) logerror("MSM5832 '%s' HOLD: %u\n", tag().c_str(), state);

	m_hold = state;
}


//-------------------------------------------------
//  read_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( msm5832_device::read_w )
{
	if (LOG) logerror("MSM5832 '%s' READ: %u\n", tag().c_str(), state);

	m_read = state;
}


//-------------------------------------------------
//  write_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( msm5832_device::write_w )
{
	if (LOG) logerror("MSM5832 '%s' WR: %u\n", tag().c_str(), state);

	m_write = state;
}


//-------------------------------------------------
//  cs_w -
//-------------------------------------------------

WRITE_LINE_MEMBER( msm5832_device::cs_w )
{
	if (LOG) logerror("MSM5832 '%s' CS: %u\n", tag().c_str(), state);

	m_cs = state;
}