mirror of
https://github.com/holub/mame
synced 2025-05-04 05:23:22 +03:00
Added MCCS1850 RTC emulation. [Curt Coder]
This commit is contained in:
parent
41f86102e9
commit
83c16c9766
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -837,6 +837,8 @@ src/emu/machine/mc6852.c svneol=native#text/plain
|
||||
src/emu/machine/mc6852.h svneol=native#text/plain
|
||||
src/emu/machine/mc68901.c svneol=native#text/plain
|
||||
src/emu/machine/mc68901.h svneol=native#text/plain
|
||||
src/emu/machine/mccs1850.c svneol=native#text/plain
|
||||
src/emu/machine/mccs1850.h svneol=native#text/plain
|
||||
src/emu/machine/microtch.c svneol=native#text/plain
|
||||
src/emu/machine/microtch.h svneol=native#text/plain
|
||||
src/emu/machine/mm74c922.c svneol=native#text/plain
|
||||
|
@ -194,6 +194,7 @@ EMUMACHINEOBJS = \
|
||||
$(EMUMACHINE)/mc146818.o \
|
||||
$(EMUMACHINE)/mc6852.o \
|
||||
$(EMUMACHINE)/mc68901.o \
|
||||
$(EMUMACHINE)/mccs1850.o \
|
||||
$(EMUMACHINE)/mm74c922.o \
|
||||
$(EMUMACHINE)/microtch.o \
|
||||
$(EMUMACHINE)/mos6529.o \
|
||||
|
584
src/emu/machine/mccs1850.c
Normal file
584
src/emu/machine/mccs1850.c
Normal file
@ -0,0 +1,584 @@
|
||||
/**********************************************************************
|
||||
|
||||
Motorola MCCS1850 Serial Real-Time Clock emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- auto restart
|
||||
- test mode
|
||||
|
||||
*/
|
||||
|
||||
#include "mccs1850.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACROS / CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define LOG 0
|
||||
|
||||
|
||||
#define RAM_SIZE 0x80
|
||||
|
||||
|
||||
// serial state
|
||||
enum
|
||||
{
|
||||
STATE_ADDRESS,
|
||||
STATE_DATA
|
||||
};
|
||||
|
||||
|
||||
// registers
|
||||
enum
|
||||
{
|
||||
REGISTER_COUNTER_LATCH = 0x20,
|
||||
REGISTER_ALARM_LATCH = 0x24,
|
||||
REGISTER_STATUS = 0x30,
|
||||
REGISTER_CONTROL = 0x31,
|
||||
REGISTER_TEST_1 = 0x3e,
|
||||
REGISTER_TEST_2 = 0x3f,
|
||||
REGISTER_TEST_KICK_START_COUNTER = 0x40,
|
||||
REGISTER_TEST_PRESCALE_COUNTER = 0x43,
|
||||
REGISTER_TEST_COUNTER_INCREMENT = 0x4f
|
||||
};
|
||||
|
||||
|
||||
// clock status/interrupt register
|
||||
#define STATUS_TM 0x20 // test mode
|
||||
#define STATUS_FTU 0x10 // first time up
|
||||
#define STATUS_IT 0x08 // interrupt true
|
||||
#define STATUS_LB 0x04 // low battery
|
||||
#define STATUS_AI 0x02 // alarm
|
||||
#define STATUS_RPD 0x01 // request to power down
|
||||
|
||||
|
||||
// clock control register
|
||||
#define CONTROL_STR_STP 0x80 // start/stop
|
||||
#define CONTROL_PD 0x40 // power down
|
||||
#define CONTROL_AR 0x20 // auto restart
|
||||
#define CONTROL_AE 0x10 // alarm enable
|
||||
#define CONTROL_AC 0x08 // alarm clear
|
||||
#define CONTROL_FTUC 0x04 // first time up clear
|
||||
#define CONTROL_LBE 0x02 // low battery enable
|
||||
#define CONTROL_RPCD 0x01 // request to power down clear
|
||||
|
||||
|
||||
// test register 1
|
||||
#define TEST1_DIV1 0x80 // divide by 1
|
||||
#define TEST1_VOVR 0x40 // Vdd override
|
||||
#define TEST1_VDDUP 0x20 // Vdd up
|
||||
#define TEST1_VDDON 0x10 // Vdd on
|
||||
#define TEST1_VRT 0x08 // valid RAM and time
|
||||
#define TEST1_LOW_BAT 0x08 // low battery
|
||||
#define TEST1_PCC 0x04 // programmable capacitor C (10.0 pF)
|
||||
#define TEST1_PCB 0x02 // programmable capacitor B (5.0 pF)
|
||||
#define TEST1_PCA 0x01 // programmable capacitor A (2.5 pF)
|
||||
|
||||
|
||||
// test register 2
|
||||
#define TEST2_OSCBY 0x80 // oscillator bypass
|
||||
#define TEST2_COMPOVR 0x40 // comparator override
|
||||
#define TEST2_POR 0x20 // power on reset
|
||||
#define TEST2_SELTCK 0x10 // select test clock
|
||||
#define TEST2_FRZ 0x08 // freeze mode
|
||||
#define TEST2_DV_MASK 0x07 // divider bits select
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
const device_type MCCS1850 = &device_creator<mccs1850_device>;
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INLINE HELPERS
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// check_interrupt -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void mccs1850_device::check_interrupt()
|
||||
{
|
||||
UINT8 status = m_ram[REGISTER_STATUS];
|
||||
UINT8 control = m_ram[REGISTER_CONTROL];
|
||||
|
||||
bool interrupt = (((status & STATUS_AI) && (control & CONTROL_AE)) // alarm interrupt
|
||||
|| ((status & STATUS_LB) && (control & CONTROL_LBE)) // low battery
|
||||
|| (status & STATUS_FTU) // first time up
|
||||
|| (status & STATUS_RPD)); // request to power down
|
||||
|
||||
if (interrupt)
|
||||
{
|
||||
m_ram[REGISTER_STATUS] |= STATUS_IT;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ram[REGISTER_STATUS] &= ~STATUS_IT;
|
||||
}
|
||||
|
||||
devcb_call_write_line(&m_out_int_func, interrupt ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_pse_line -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void mccs1850_device::set_pse_line(int state)
|
||||
{
|
||||
m_pse = state;
|
||||
|
||||
devcb_call_write_line(&m_out_pse_func, m_pse);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_register -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline UINT8 mccs1850_device::read_register(offs_t offset)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REGISTER_COUNTER_LATCH:
|
||||
// load counter value into latch
|
||||
m_ram[REGISTER_COUNTER_LATCH] = m_counter >> 24;
|
||||
m_ram[REGISTER_COUNTER_LATCH + 1] = m_counter >> 16;
|
||||
m_ram[REGISTER_COUNTER_LATCH + 2] = m_counter >> 8;
|
||||
m_ram[REGISTER_COUNTER_LATCH + 3] = m_counter;
|
||||
break;
|
||||
|
||||
case REGISTER_TEST_1:
|
||||
case REGISTER_TEST_2:
|
||||
case REGISTER_TEST_KICK_START_COUNTER:
|
||||
case REGISTER_TEST_PRESCALE_COUNTER:
|
||||
case REGISTER_TEST_COUNTER_INCREMENT:
|
||||
logerror("MCCS1850 '%s' Unsupported read from test register %02x!\n", tag(), offset);
|
||||
break;
|
||||
}
|
||||
|
||||
return m_ram[offset];
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_register -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void mccs1850_device::write_register(offs_t offset, UINT8 data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REGISTER_STATUS:
|
||||
// read only
|
||||
break;
|
||||
|
||||
case REGISTER_CONTROL:
|
||||
if (LOG) logerror("MCCS1850 '%s' Counter %s\n", tag(), (data & CONTROL_STR_STP) ? "Start" : "Stop");
|
||||
m_clock_timer->enable(data & CONTROL_STR_STP);
|
||||
|
||||
if (data & CONTROL_PD)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' Power Down\n", tag());
|
||||
set_pse_line(0);
|
||||
}
|
||||
|
||||
if (data & CONTROL_AR)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' Auto Restart\n", tag());
|
||||
}
|
||||
|
||||
if (data & CONTROL_AC)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' Alarm Clear\n", tag());
|
||||
m_ram[REGISTER_STATUS] &= ~STATUS_AI;
|
||||
}
|
||||
|
||||
if (data & CONTROL_FTUC)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' First Time Up Clear\n", tag());
|
||||
m_ram[REGISTER_STATUS] &= ~STATUS_FTU;
|
||||
}
|
||||
|
||||
if (data & CONTROL_RPCD)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' Request to Power Down Clear\n", tag());
|
||||
m_ram[REGISTER_STATUS] &= ~STATUS_RPD;
|
||||
}
|
||||
|
||||
m_ram[REGISTER_CONTROL] = data & 0xb2;
|
||||
|
||||
check_interrupt();
|
||||
break;
|
||||
|
||||
case REGISTER_TEST_1:
|
||||
case REGISTER_TEST_2:
|
||||
case REGISTER_TEST_KICK_START_COUNTER:
|
||||
case REGISTER_TEST_PRESCALE_COUNTER:
|
||||
case REGISTER_TEST_COUNTER_INCREMENT:
|
||||
logerror("MCCS1850 '%s' Unsupported write to test register %02x!\n", tag(), offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
m_ram[offset] = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// advance_seconds -
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void mccs1850_device::advance_seconds()
|
||||
{
|
||||
UINT32 alarm = (m_ram[REGISTER_ALARM_LATCH] << 24) | (m_ram[REGISTER_ALARM_LATCH + 1] << 16) | (m_ram[REGISTER_ALARM_LATCH + 2] << 8) | m_ram[REGISTER_ALARM_LATCH + 3];
|
||||
|
||||
m_counter++;
|
||||
|
||||
if (m_counter == alarm)
|
||||
{
|
||||
if (m_pse)
|
||||
{
|
||||
// trigger alarm
|
||||
m_ram[REGISTER_STATUS] |= STATUS_AI;
|
||||
|
||||
check_interrupt();
|
||||
}
|
||||
else
|
||||
{
|
||||
// wake up
|
||||
set_pse_line(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// mccs1850_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
mccs1850_device::mccs1850_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, MCCS1850, "MCCS1850", tag, owner, clock),
|
||||
device_rtc_interface(mconfig, *this),
|
||||
device_nvram_interface(mconfig, *this),
|
||||
m_pse(1),
|
||||
m_ce(0),
|
||||
m_sck(0),
|
||||
m_sdo(0),
|
||||
m_sdi(0),
|
||||
m_state(STATE_ADDRESS),
|
||||
m_bits(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::device_config_complete()
|
||||
{
|
||||
// inherit a copy of the static data
|
||||
const mccs1850_interface *intf = reinterpret_cast<const mccs1850_interface *>(static_config());
|
||||
if (intf != NULL)
|
||||
*static_cast<mccs1850_interface *>(this) = *intf;
|
||||
|
||||
// or initialize to defaults if none provided
|
||||
else
|
||||
{
|
||||
memset(&m_out_int_cb, 0, sizeof(m_out_int_cb));
|
||||
memset(&m_out_pse_cb, 0, sizeof(m_out_pse_cb));
|
||||
memset(&m_out_nuc_cb, 0, sizeof(m_out_nuc_cb));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
devcb_resolve_write_line(&m_out_int_func, &m_out_int_cb, this);
|
||||
devcb_resolve_write_line(&m_out_pse_func, &m_out_pse_cb, this);
|
||||
devcb_resolve_write_line(&m_out_nuc_func, &m_out_nuc_cb, 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));
|
||||
|
||||
// state saving
|
||||
save_item(NAME(m_pse));
|
||||
save_item(NAME(m_counter));
|
||||
save_item(NAME(m_ce));
|
||||
save_item(NAME(m_sck));
|
||||
save_item(NAME(m_sdo));
|
||||
save_item(NAME(m_sdi));
|
||||
save_item(NAME(m_state));
|
||||
save_item(NAME(m_address));
|
||||
save_item(NAME(m_bits));
|
||||
save_item(NAME(m_shift));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::device_reset()
|
||||
{
|
||||
memset(m_ram, 0xff, RAM_SIZE);
|
||||
|
||||
m_ram[REGISTER_STATUS] = 0x80 | STATUS_FTU;
|
||||
m_ram[REGISTER_CONTROL] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_CLOCK:
|
||||
advance_seconds();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rtc_set_time - called to initialize the RTC to
|
||||
// a known state
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::rtc_set_time(int year, int month, int day, int day_of_week, int hour, int minute, int second)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_default - called to initialize NVRAM to
|
||||
// its default state
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::nvram_default()
|
||||
{
|
||||
memset(m_ram, 0xff, RAM_SIZE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_read - called to read NVRAM from the
|
||||
// .nv file
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::nvram_read(emu_file &file)
|
||||
{
|
||||
file.read(m_ram, RAM_SIZE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_write - called to write NVRAM to the
|
||||
// .nv file
|
||||
//-------------------------------------------------
|
||||
|
||||
void mccs1850_device::nvram_write(emu_file &file)
|
||||
{
|
||||
file.write(m_ram, RAM_SIZE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ce_w - chip enable write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( mccs1850_device::ce_w )
|
||||
{
|
||||
m_ce = state;
|
||||
|
||||
if (!m_ce)
|
||||
{
|
||||
m_state = STATE_ADDRESS;
|
||||
m_bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sck_w - serial clock write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( mccs1850_device::sck_w )
|
||||
{
|
||||
if (!m_ce) return;
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case STATE_ADDRESS:
|
||||
if (m_sck && !state)
|
||||
{
|
||||
m_address <<= 1;
|
||||
m_address |= m_sdi;
|
||||
m_bits++;
|
||||
|
||||
if (m_bits == 8)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' %s Address %u\n", tag(), BIT(m_address, 7) ? "Read" : "Write", m_address & 0x7f);
|
||||
|
||||
m_bits = 0;
|
||||
m_state = STATE_DATA;
|
||||
|
||||
if (BIT(m_address, 7))
|
||||
{
|
||||
m_shift = read_register(m_address & 0x7f);
|
||||
|
||||
if (LOG) logerror("MCCS1850 '%s' Data Out %02x\n", tag(), m_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_DATA:
|
||||
if (!BIT(m_address, 7) && m_sck && !state)
|
||||
{
|
||||
// shift data in
|
||||
m_shift <<= 1;
|
||||
m_shift |= m_sdi;
|
||||
m_bits++;
|
||||
|
||||
if (m_bits == 8)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' Data In %02x\n", tag(), m_shift);
|
||||
|
||||
write_register(m_address & 0x7f, m_shift);
|
||||
|
||||
m_bits = 0;
|
||||
|
||||
// increment address counter
|
||||
m_address++;
|
||||
m_address &= 0x7f;
|
||||
}
|
||||
}
|
||||
else if (BIT(m_address, 7) && !m_sck && state)
|
||||
{
|
||||
// shift data out
|
||||
m_sdo = BIT(m_shift, 7);
|
||||
m_shift <<= 1;
|
||||
m_bits++;
|
||||
|
||||
if (m_bits == 8)
|
||||
{
|
||||
m_bits = 0;
|
||||
|
||||
// increment address counter
|
||||
m_address++;
|
||||
m_address &= 0x7f;
|
||||
m_shift = read_register(m_address & 0x7f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_sck = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sdo_r - serial data out read
|
||||
//-------------------------------------------------
|
||||
|
||||
READ_LINE_MEMBER( mccs1850_device::sdo_r )
|
||||
{
|
||||
return m_sdo;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sdi_w - serial data in write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( mccs1850_device::sdi_w )
|
||||
{
|
||||
m_sdi = state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// pwrsw_w - power switch write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( mccs1850_device::pwrsw_w )
|
||||
{
|
||||
if (!state)
|
||||
{
|
||||
if (m_pse)
|
||||
{
|
||||
// request to power down
|
||||
m_ram[REGISTER_STATUS] |= STATUS_RPD;
|
||||
check_interrupt();
|
||||
}
|
||||
|
||||
set_pse_line(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// por_w - power on reset write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( mccs1850_device::por_w )
|
||||
{
|
||||
if (!state)
|
||||
{
|
||||
device_reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// test_w - test mode write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( mccs1850_device::test_w )
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' Test Mode\n", tag());
|
||||
|
||||
m_ram[REGISTER_STATUS] |= STATUS_TM;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG) logerror("MCCS1850 '%s' Normal Operation\n", tag());
|
||||
|
||||
m_ram[REGISTER_STATUS] &= ~STATUS_TM;
|
||||
}
|
||||
}
|
135
src/emu/machine/mccs1850.h
Normal file
135
src/emu/machine/mccs1850.h
Normal file
@ -0,0 +1,135 @@
|
||||
/**********************************************************************
|
||||
|
||||
Motorola MCCS1850 Serial Real-Time Clock emulation
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************
|
||||
_____ _____
|
||||
Vbat 1 |* \_/ | 16 Vdd
|
||||
_POR 2 | | 15 TEST
|
||||
_INT 3 | | 14 XTAL1
|
||||
SCK 4 | MCCS1850 | 13 XTAL2
|
||||
SDI 5 | | 12 _PWRSW
|
||||
SDO 6 | | 11 NUC
|
||||
CE 7 | | 10 _PSE
|
||||
Vss 8 |_____________| 9 PSE
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __MCCS1850__
|
||||
#define __MCCS1850__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_MCCS1850_ADD(_tag, _clock, _config) \
|
||||
MCFG_DEVICE_ADD(_tag, MCCS1850, _clock) \
|
||||
MCFG_DEVICE_CONFIG(_config)
|
||||
|
||||
|
||||
#define MCCS1850_INTERFACE(name) \
|
||||
const mccs1850_interface (name) =
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> mccs1850_interface
|
||||
|
||||
struct mccs1850_interface
|
||||
{
|
||||
devcb_write_line m_out_int_cb;
|
||||
devcb_write_line m_out_pse_cb;
|
||||
devcb_write_line m_out_nuc_cb;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ======================> mccs1850_device
|
||||
|
||||
class mccs1850_device : public device_t,
|
||||
public device_rtc_interface,
|
||||
public device_nvram_interface,
|
||||
public mccs1850_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
mccs1850_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( ce_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( sck_w );
|
||||
DECLARE_READ_LINE_MEMBER( sdo_r );
|
||||
DECLARE_WRITE_LINE_MEMBER( sdi_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( pwrsw_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( por_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( test_w );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete();
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
// device_rtc_interface overrides
|
||||
virtual void rtc_set_time(int year, int month, int day, int day_of_week, int hour, int minute, int second);
|
||||
virtual bool rtc_is_year_2000_compliant() { return false; }
|
||||
|
||||
// device_nvram_interface overrides
|
||||
virtual void nvram_default();
|
||||
virtual void nvram_read(emu_file &file);
|
||||
virtual void nvram_write(emu_file &file);
|
||||
|
||||
private:
|
||||
inline void check_interrupt();
|
||||
inline void set_pse_line(int state);
|
||||
inline UINT8 read_register(offs_t offset);
|
||||
inline void write_register(offs_t offset, UINT8 data);
|
||||
inline void advance_seconds();
|
||||
|
||||
static const device_timer_id TIMER_CLOCK = 0;
|
||||
|
||||
devcb_resolved_write_line m_out_int_func;
|
||||
devcb_resolved_write_line m_out_pse_func;
|
||||
devcb_resolved_write_line m_out_nuc_func;
|
||||
|
||||
UINT8 m_ram[0x80]; // RAM
|
||||
|
||||
// power supply
|
||||
int m_pse; // power supply enable
|
||||
|
||||
// counter
|
||||
UINT32 m_counter; // seconds counter
|
||||
|
||||
// serial interface
|
||||
int m_ce; // chip enable
|
||||
int m_sck; // serial clock
|
||||
int m_sdo; // serial data out
|
||||
int m_sdi; // serial data in
|
||||
int m_state; // serial interface state
|
||||
UINT8 m_address; // address counter
|
||||
int m_bits; // bit counter
|
||||
UINT8 m_shift; // shift register
|
||||
|
||||
// timers
|
||||
emu_timer *m_clock_timer;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type MCCS1850;
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user