mirror of
https://github.com/holub/mame
synced 2025-05-02 20:46:41 +03:00
Imported MSM5832 RTC from MESS. (no whatsnew)
This commit is contained in:
parent
c972282319
commit
4f3f0decb8
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -928,6 +928,10 @@ src/emu/mconfig.h svneol=native#text/plain
|
||||
src/emu/memconv.h svneol=native#text/plain
|
||||
src/emu/memory.c svneol=native#text/plain
|
||||
src/emu/memory.h svneol=native#text/plain
|
||||
src/emu/msm5832.c svneol=native#text/plain
|
||||
src/emu/msm5832.h svneol=native#text/plain
|
||||
src/emu/msm58321.c svneol=native#text/plain
|
||||
src/emu/msm58321.h svneol=native#text/plain
|
||||
src/emu/output.c svneol=native#text/plain
|
||||
src/emu/output.h svneol=native#text/plain
|
||||
src/emu/profiler.c svneol=native#text/plain
|
||||
|
@ -193,6 +193,7 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/mc146818.o \
|
||||
$(EMUMACHINE)/mc6852.o \
|
||||
$(EMUMACHINE)/mc68901.o \
|
||||
$(EMUMACHINE)/msm5832.o \
|
||||
$(EMUMACHINE)/msm58321.o \
|
||||
$(EMUMACHINE)/microtch.o \
|
||||
$(EMUMACHINE)/mos6529.o \
|
||||
|
375
src/emu/msm5832.c
Normal file
375
src/emu/msm5832.c
Normal file
@ -0,0 +1,375 @@
|
||||
/**********************************************************************
|
||||
|
||||
OKI MSM5832 Real Time Clock/Calendar emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- 12/24 hour
|
||||
- AM/PM
|
||||
- leap year
|
||||
- test input
|
||||
- reference signal output
|
||||
|
||||
*/
|
||||
|
||||
#include "msm5832.h"
|
||||
#include "machine/devhelpr.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// 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
|
||||
};
|
||||
|
||||
|
||||
// days per month
|
||||
static const int DAYS_PER_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// devices
|
||||
const device_type MSM5832 = msm5832_device_config::static_alloc_device_config;
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE CONFIGURATION
|
||||
//**************************************************************************
|
||||
|
||||
GENERIC_DEVICE_CONFIG_SETUP(msm5832, "MSM5832")
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// advance_seconds -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void msm5832_device::advance_seconds()
|
||||
{
|
||||
int seconds = read_counter(REGISTER_S1);
|
||||
|
||||
seconds++;
|
||||
|
||||
if (seconds > 59)
|
||||
{
|
||||
seconds = 0;
|
||||
|
||||
advance_minutes();
|
||||
}
|
||||
|
||||
write_counter(REGISTER_S1, seconds);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// advance_minutes -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void msm5832_device::advance_minutes()
|
||||
{
|
||||
int minutes = read_counter(REGISTER_MI1);
|
||||
int hours = read_counter(REGISTER_H1);
|
||||
int days = read_counter(REGISTER_D1);
|
||||
int month = read_counter(REGISTER_MO1);
|
||||
int year = read_counter(REGISTER_Y1);
|
||||
int day_of_week = m_reg[REGISTER_W];
|
||||
|
||||
minutes++;
|
||||
|
||||
if (minutes > 59)
|
||||
{
|
||||
minutes = 0;
|
||||
hours++;
|
||||
}
|
||||
|
||||
if (hours > 23)
|
||||
{
|
||||
hours = 0;
|
||||
days++;
|
||||
day_of_week++;
|
||||
}
|
||||
|
||||
if (day_of_week > 6)
|
||||
{
|
||||
day_of_week++;
|
||||
}
|
||||
|
||||
if (days > DAYS_PER_MONTH[month - 1])
|
||||
{
|
||||
days = 1;
|
||||
month++;
|
||||
}
|
||||
|
||||
if (month > 12)
|
||||
{
|
||||
month = 1;
|
||||
year++;
|
||||
}
|
||||
|
||||
if (year > 99)
|
||||
{
|
||||
year = 0;
|
||||
}
|
||||
|
||||
write_counter(REGISTER_MI1, minutes);
|
||||
write_counter(REGISTER_H1, hours);
|
||||
write_counter(REGISTER_D1, days);
|
||||
write_counter(REGISTER_MO1, month);
|
||||
write_counter(REGISTER_Y1, year);
|
||||
m_reg[REGISTER_W] = day_of_week;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// msm5832_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
msm5832_device::msm5832_device(running_machine &_machine, const msm5832_device_config &config)
|
||||
: device_t(_machine, config),
|
||||
m_hold(0),
|
||||
m_address(0),
|
||||
m_read(0),
|
||||
m_write(0),
|
||||
m_cs(0),
|
||||
m_config(config)
|
||||
{
|
||||
for (int i = 0; i < 13; i++)
|
||||
m_reg[i] = 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_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// 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
|
||||
{
|
||||
data = m_reg[m_address];
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG) logerror("MSM5832 '%s' Register Read %01x: %01x\n", tag(), 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(), m_address, data & 0x0f);
|
||||
|
||||
if (m_cs && m_write)
|
||||
{
|
||||
m_reg[m_address] = data & 0x0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// address_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
void msm5832_device::address_w(UINT8 data)
|
||||
{
|
||||
if (LOG) logerror("MSM5832 '%s' Address: %01x\n", tag(), 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(), state);
|
||||
|
||||
if (state)
|
||||
{
|
||||
int seconds = read_counter(REGISTER_S1);
|
||||
|
||||
if (seconds < 30)
|
||||
{
|
||||
write_counter(REGISTER_S1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_counter(REGISTER_S1, 0);
|
||||
advance_minutes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// test_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm5832_device::test_w )
|
||||
{
|
||||
if (LOG) logerror("MSM5832 '%s' TEST: %u\n", tag(), state);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// hold_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm5832_device::hold_w )
|
||||
{
|
||||
if (LOG) logerror("MSM5832 '%s' HOLD: %u\n", tag(), state);
|
||||
|
||||
m_hold = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm5832_device::read_w )
|
||||
{
|
||||
if (LOG) logerror("MSM5832 '%s' READ: %u\n", tag(), state);
|
||||
|
||||
m_read = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm5832_device::write_w )
|
||||
{
|
||||
if (LOG) logerror("MSM5832 '%s' WR: %u\n", tag(), state);
|
||||
|
||||
m_write = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// cs_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm5832_device::cs_w )
|
||||
{
|
||||
if (LOG) logerror("MSM5832 '%s' CS: %u\n", tag(), state);
|
||||
|
||||
m_cs = state;
|
||||
}
|
118
src/emu/msm5832.h
Normal file
118
src/emu/msm5832.h
Normal file
@ -0,0 +1,118 @@
|
||||
/**********************************************************************
|
||||
|
||||
OKI MSM5832 Real Time Clock/Calendar emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************
|
||||
_____ _____
|
||||
Vdd 1 |* \_/ | 18 HOLD
|
||||
WRITE 2 | | 17 _XT
|
||||
READ 3 | | 16 XT
|
||||
A0 4 | | 15 +- 30 ADJ
|
||||
A1 5 | MSM5832 | 14 TEST
|
||||
A2 6 | | 13 GND
|
||||
A3 7 | | 12 D3
|
||||
CS 8 | | 11 D2
|
||||
D0 9 |_____________| 10 D1
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __MSM5832__
|
||||
#define __MSM5832__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_MSM5832_ADD(_tag, _clock) \
|
||||
MCFG_DEVICE_ADD(_tag, MSM5832, _clock)
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> msm5832_device_config
|
||||
|
||||
class msm5832_device_config : public device_config
|
||||
{
|
||||
friend class msm5832_device;
|
||||
|
||||
// construction/destruction
|
||||
msm5832_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||
|
||||
public:
|
||||
// allocators
|
||||
static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||
virtual device_t *alloc_device(running_machine &machine) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ======================> msm5832_device
|
||||
|
||||
class msm5832_device : public device_t
|
||||
{
|
||||
friend class msm5832_device_config;
|
||||
|
||||
// construction/destruction
|
||||
msm5832_device(running_machine &_machine, const msm5832_device_config &_config);
|
||||
|
||||
public:
|
||||
DECLARE_READ8_MEMBER( data_r );
|
||||
DECLARE_WRITE8_MEMBER( data_w );
|
||||
|
||||
void address_w(UINT8 data);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( adj_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( test_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( hold_w );
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( read_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( write_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( cs_w );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
private:
|
||||
static const device_timer_id TIMER_CLOCK = 0;
|
||||
|
||||
inline int read_counter(int counter);
|
||||
inline void write_counter(int counter, int value);
|
||||
inline void advance_seconds();
|
||||
inline void advance_minutes();
|
||||
|
||||
UINT8 m_reg[13]; // registers
|
||||
|
||||
int m_hold; // counter hold
|
||||
int m_address; // address
|
||||
|
||||
int m_read;
|
||||
int m_write;
|
||||
int m_cs;
|
||||
|
||||
// timers
|
||||
emu_timer *m_clock_timer;
|
||||
|
||||
const msm5832_device_config &m_config;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type MSM5832;
|
||||
|
||||
|
||||
|
||||
#endif
|
450
src/emu/msm58321.c
Normal file
450
src/emu/msm58321.c
Normal file
@ -0,0 +1,450 @@
|
||||
/**********************************************************************
|
||||
|
||||
OKI MSM58321RS Real Time Clock/Calendar emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- 12/24 hour
|
||||
- AM/PM
|
||||
- leap year
|
||||
- stop
|
||||
- reset
|
||||
- reference registers
|
||||
|
||||
*/
|
||||
|
||||
#include "msm58321.h"
|
||||
#include "machine/devhelpr.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACROS / CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define LOG 1
|
||||
|
||||
|
||||
// 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_RESET,
|
||||
REGISTER_REF0,
|
||||
REGISTER_REF1
|
||||
};
|
||||
|
||||
|
||||
// days per month
|
||||
static const int DAYS_PER_MONTH[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// devices
|
||||
const device_type MSM58321 = msm58321_device_config::static_alloc_device_config;
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE CONFIGURATION
|
||||
//**************************************************************************
|
||||
|
||||
GENERIC_DEVICE_CONFIG_SETUP(msm58321, "MSM58321")
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void msm58321_device_config::device_config_complete()
|
||||
{
|
||||
// inherit a copy of the static data
|
||||
const msm58321_interface *intf = reinterpret_cast<const msm58321_interface *>(static_config());
|
||||
if (intf != NULL)
|
||||
*static_cast<msm58321_interface *>(this) = *intf;
|
||||
|
||||
// or initialize to defaults if none provided
|
||||
else
|
||||
{
|
||||
memset(&m_out_busy_func, 0, sizeof(m_out_busy_func));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INLINE HELPERS
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_counter -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline int msm58321_device::read_counter(int counter)
|
||||
{
|
||||
return (m_reg[counter + 1] * 10) + m_reg[counter];
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_counter -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void msm58321_device::write_counter(int counter, int value)
|
||||
{
|
||||
m_reg[counter] = value % 10;
|
||||
m_reg[counter + 1] = value / 10;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// advance_seconds -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void msm58321_device::advance_seconds()
|
||||
{
|
||||
int seconds = read_counter(REGISTER_S1);
|
||||
|
||||
seconds++;
|
||||
|
||||
if (seconds > 59)
|
||||
{
|
||||
seconds = 0;
|
||||
|
||||
advance_minutes();
|
||||
}
|
||||
|
||||
write_counter(REGISTER_S1, seconds);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// advance_minutes -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void msm58321_device::advance_minutes()
|
||||
{
|
||||
int minutes = read_counter(REGISTER_MI1);
|
||||
int hours = read_counter(REGISTER_H1);
|
||||
int days = read_counter(REGISTER_D1);
|
||||
int month = read_counter(REGISTER_MO1);
|
||||
int year = read_counter(REGISTER_Y1);
|
||||
int day_of_week = m_reg[REGISTER_W];
|
||||
|
||||
minutes++;
|
||||
|
||||
if (minutes > 59)
|
||||
{
|
||||
minutes = 0;
|
||||
hours++;
|
||||
}
|
||||
|
||||
if (hours > 23)
|
||||
{
|
||||
hours = 0;
|
||||
days++;
|
||||
day_of_week++;
|
||||
}
|
||||
|
||||
if (day_of_week > 6)
|
||||
{
|
||||
day_of_week++;
|
||||
}
|
||||
|
||||
if (days > DAYS_PER_MONTH[month - 1])
|
||||
{
|
||||
days = 1;
|
||||
month++;
|
||||
}
|
||||
|
||||
if (month > 12)
|
||||
{
|
||||
month = 1;
|
||||
year++;
|
||||
}
|
||||
|
||||
if (year > 99)
|
||||
{
|
||||
year = 0;
|
||||
}
|
||||
|
||||
write_counter(REGISTER_MI1, minutes);
|
||||
write_counter(REGISTER_H1, hours);
|
||||
write_counter(REGISTER_D1, days);
|
||||
write_counter(REGISTER_MO1, month);
|
||||
write_counter(REGISTER_Y1, year);
|
||||
m_reg[REGISTER_W] = day_of_week;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// msm58321_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
msm58321_device::msm58321_device(running_machine &_machine, const msm58321_device_config &config)
|
||||
: device_t(_machine, config),
|
||||
m_config(config)
|
||||
{
|
||||
for (int i = 0; i < 13; i++)
|
||||
m_reg[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void msm58321_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
devcb_resolve_write_line(&m_out_busy_func, &m_config.m_out_busy_func, this);
|
||||
|
||||
// allocate timers
|
||||
m_clock_timer = timer_alloc(TIMER_CLOCK);
|
||||
m_clock_timer->adjust(attotime::from_hz(clock() / 32768), 0, attotime::from_hz(clock() / 32768));
|
||||
|
||||
m_busy_timer = timer_alloc(TIMER_BUSY);
|
||||
m_busy_timer->adjust(attotime::from_hz(clock() / 16384), 0, attotime::from_hz(clock() / 16384));
|
||||
|
||||
// state saving
|
||||
save_item(NAME(m_cs1));
|
||||
save_item(NAME(m_cs2));
|
||||
save_item(NAME(m_busy));
|
||||
save_item(NAME(m_read));
|
||||
save_item(NAME(m_write));
|
||||
save_item(NAME(m_address_write));
|
||||
save_item(NAME(m_reg));
|
||||
save_item(NAME(m_latch));
|
||||
save_item(NAME(m_address));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
|
||||
void msm58321_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_CLOCK:
|
||||
advance_seconds();
|
||||
break;
|
||||
|
||||
case TIMER_BUSY:
|
||||
devcb_call_write_line(&m_out_busy_func, m_busy);
|
||||
m_busy = !m_busy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read -
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER( msm58321_device::read )
|
||||
{
|
||||
UINT8 data = 0;
|
||||
|
||||
if (m_cs1 && m_cs2)
|
||||
{
|
||||
if (m_read)
|
||||
{
|
||||
switch (m_address)
|
||||
{
|
||||
case REGISTER_RESET:
|
||||
break;
|
||||
|
||||
case REGISTER_REF0:
|
||||
case REGISTER_REF1:
|
||||
break;
|
||||
|
||||
default:
|
||||
data = m_reg[m_address];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_write)
|
||||
{
|
||||
if (m_address >= REGISTER_REF0)
|
||||
{
|
||||
// TODO: output reference values
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LOG) logerror("MSM58321 '%s' Register Read %01x: %01x\n", tag(), m_address, data & 0x0f);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE8_MEMBER( msm58321_device::write )
|
||||
{
|
||||
// latch data for future use
|
||||
m_latch = data & 0x0f;
|
||||
|
||||
if (!m_cs1 || !m_cs2) return;
|
||||
|
||||
if (m_address_write)
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' Latch Address %01x\n", tag(), m_latch);
|
||||
|
||||
// latch address
|
||||
m_address = m_latch;
|
||||
}
|
||||
|
||||
if (m_write)
|
||||
{
|
||||
switch(m_address)
|
||||
{
|
||||
case REGISTER_RESET:
|
||||
if (LOG) logerror("MSM58321 '%s' Reset\n", tag());
|
||||
break;
|
||||
|
||||
case REGISTER_REF0:
|
||||
case REGISTER_REF1:
|
||||
if (LOG) logerror("MSM58321 '%s' Reference Signal\n", tag());
|
||||
break;
|
||||
|
||||
default:
|
||||
if (LOG) logerror("MSM58321 '%s' Register Write %01x: %01x\n", tag(), m_address, data & 0x0f);
|
||||
m_reg[m_address] = m_latch & 0x0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// cs1_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm58321_device::cs1_w )
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' CS1: %u\n", tag(), state);
|
||||
|
||||
m_cs1 = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// cs2_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm58321_device::cs2_w )
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' CS2: %u\n", tag(), state);
|
||||
|
||||
m_cs2 = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm58321_device::read_w )
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' READ: %u\n", tag(), state);
|
||||
|
||||
m_read = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm58321_device::write_w )
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' WRITE: %u\n", tag(), state);
|
||||
|
||||
m_write = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// address_write_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm58321_device::address_write_w )
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' ADDRESS WRITE: %u\n", tag(), state);
|
||||
|
||||
m_address_write = state;
|
||||
|
||||
if (m_address_write)
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' Latch Address %01x\n", tag(), m_latch);
|
||||
|
||||
// latch address
|
||||
m_address = m_latch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// stop_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm58321_device::stop_w )
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' STOP: %u\n", tag(), state);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// test_w -
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( msm58321_device::test_w )
|
||||
{
|
||||
if (LOG) logerror("MSM58321 '%s' TEST: %u\n", tag(), state);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// busy_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
READ_LINE_MEMBER( msm58321_device::busy_r )
|
||||
{
|
||||
return m_busy;
|
||||
}
|
140
src/emu/msm58321.h
Normal file
140
src/emu/msm58321.h
Normal file
@ -0,0 +1,140 @@
|
||||
/**********************************************************************
|
||||
|
||||
OKI MSM58321RS Real Time Clock/Calendar emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************
|
||||
_____ _____
|
||||
CS2 1 |* \_/ | 16 Vdd
|
||||
WRITE 2 | | 15 XT
|
||||
READ 3 | | 14 _XT
|
||||
D0 4 | MSM58321 | 13 CS1
|
||||
D1 5 | RTC58321 | 12 TEST
|
||||
D2 6 | | 11 STOP
|
||||
D3 7 | | 10 _BUSY
|
||||
GND 8 |_____________| 9 ADDRESS WRITE
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __MSM58321__
|
||||
#define __MSM58321__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_MSM58321_ADD(_tag, _clock, _config) \
|
||||
MCFG_DEVICE_ADD(_tag, MSM58321, _clock) \
|
||||
MCFG_DEVICE_CONFIG(_config)
|
||||
|
||||
#define MSM58321_INTERFACE(name) \
|
||||
const msm58321_interface (name) =
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> msm58321_interface
|
||||
|
||||
struct msm58321_interface
|
||||
{
|
||||
devcb_write_line m_out_busy_func;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ======================> msm58321_device_config
|
||||
|
||||
class msm58321_device_config : public device_config,
|
||||
public msm58321_interface
|
||||
{
|
||||
friend class msm58321_device;
|
||||
|
||||
// construction/destruction
|
||||
msm58321_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||
|
||||
public:
|
||||
// allocators
|
||||
static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
|
||||
virtual device_t *alloc_device(running_machine &machine) const;
|
||||
|
||||
protected:
|
||||
// device_config overrides
|
||||
virtual void device_config_complete();
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ======================> msm58321_device
|
||||
|
||||
class msm58321_device : public device_t
|
||||
{
|
||||
friend class msm58321_device_config;
|
||||
|
||||
// construction/destruction
|
||||
msm58321_device(running_machine &_machine, const msm58321_device_config &_config);
|
||||
|
||||
public:
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( cs1_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( cs2_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( read_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( write_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( address_write_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( stop_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( test_w );
|
||||
DECLARE_READ_LINE_MEMBER( busy_r );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
private:
|
||||
static const device_timer_id TIMER_CLOCK = 0;
|
||||
static const device_timer_id TIMER_BUSY = 1;
|
||||
|
||||
inline int read_counter(int counter);
|
||||
inline void write_counter(int counter, int value);
|
||||
inline void advance_seconds();
|
||||
inline void advance_minutes();
|
||||
|
||||
devcb_resolved_write_line m_out_busy_func;
|
||||
|
||||
int m_cs1; // chip select 1
|
||||
int m_cs2; // chip select 2
|
||||
int m_busy; // busy flag
|
||||
int m_read; // read data
|
||||
int m_write; // write data
|
||||
int m_address_write; // write address
|
||||
|
||||
UINT8 m_reg[13]; // registers
|
||||
UINT8 m_latch; // data latch (not present in real chip)
|
||||
UINT8 m_address; // address latch
|
||||
|
||||
// timers
|
||||
emu_timer *m_clock_timer;
|
||||
emu_timer *m_busy_timer;
|
||||
|
||||
const msm58321_device_config &m_config;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type MSM58321;
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user