Preliminary support for National Semiconductor MM58167 real-time clock/calendar. [R. Belmont]

This commit is contained in:
R. Belmont 2014-02-17 02:49:35 +00:00
parent 8ac187fe1d
commit cc0a824aff
8 changed files with 269 additions and 0 deletions

2
.gitattributes vendored
View File

@ -1996,6 +1996,8 @@ src/emu/machine/mcf5206e.c svneol=native#text/plain
src/emu/machine/mcf5206e.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/mm58167.c svneol=native#text/plain
src/emu/machine/mm58167.h svneol=native#text/plain
src/emu/machine/mm58274c.c svneol=native#text/plain
src/emu/machine/mm58274c.h svneol=native#text/plain
src/emu/machine/mm74c922.c svneol=native#text/plain

View File

@ -1606,3 +1606,12 @@ ifneq ($(filter NCR5380N,$(MACHINES)),)
MACHINEOBJS += $(MACHINEOBJ)/ncr5380n.o
endif
#-------------------------------------------------
#
#@src/emu/machine/mm58167.h,MACHINES += MM58167
#-------------------------------------------------
ifneq ($(filter MM58167,$(MACHINES)),)
MACHINEOBJS += $(MACHINEOBJ)/mm58167.o
endif

167
src/emu/machine/mm58167.c Normal file
View File

@ -0,0 +1,167 @@
/**********************************************************************
mm58167.c - National Semiconductor MM58167 real-time clock emulation
TODO: alarms and IRQs not used by the Apple /// and aren't implemented.
**********************************************************************/
#include "mm58167.h"
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
// device type definition
const device_type MM58167 = &device_creator<mm58167_device>;
// registers (0-7 are the live data, 8-f are the setting for the compare IRQ)
typedef enum
{
R_CNT_MILLISECONDS = 0, // 0 = milliseconds
R_CNT_HUNDTENTHS, // 1 = hundreds and tenths of seconds
R_CNT_SECONDS, // 2 = seconds
R_CNT_MINUTES, // 3 = minutes
R_CNT_HOURS, // 4 = hours
R_CNT_DAYOFWEEK, // 5 = day of the week
R_CNT_DAYOFMONTH, // 6 = day of the month
R_CNT_MONTH, // 7 = month
R_RAM_MILLISECONDS, // 8 = milliseconds
R_RAM_HUNDTENTHS, // 9 = hundreds and tenths of seconds
R_RAM_SECONDS, // a = seconds
R_RAM_MINUTES, // b = minutes
R_RAM_HOURS, // c = hours
R_RAM_DAYOFWEEK, // d = day of the week
R_RAM_DAYOFMONTH, // e = day of the month
R_RAM_MONTH, // f = month
R_CTL_IRQSTATUS, // 10 = IRQ status (b7 = compare, b6 = 10th sec, b5 = sec, b4 = min, b3 = hour, b2 = day, b1 = week, b0 = month)
R_CTL_IRQCONTROL, // 11 = IRQ control (same bit layout as status, but write here to enable/disable/clear)
R_CTL_RESETCOUNTERS, // 12 = reset counters
R_CTL_RESETRAM, // 13 = reset RAM
R_CTL_STATUS, // 14 = status bit
R_CTL_GOCMD, // 15 = GO Command
R_CTL_STANDBYIRQ, // 16 = standby IRQ
R_CTL_TESTMODE // 17 = test mode
} mm58167_regs_t;
//-------------------------------------------------
// mm58167_device - constructor
//-------------------------------------------------
mm58167_device::mm58167_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MM58167, "National Semiconductor MM58167", tag, owner, clock, "mm58167", __FILE__),
device_rtc_interface(mconfig, *this),
m_irq_w(*this)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void mm58167_device::device_start()
{
// allocate timers
m_clock_timer = timer_alloc();
m_clock_timer->adjust(attotime::from_hz(clock() / 32.768f), 0, attotime::from_hz(clock() / 32.768f));
m_irq_w.resolve_safe();
// state saving
save_item(NAME(m_regs));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void mm58167_device::device_reset()
{
set_current_time(machine());
m_regs[R_CTL_STATUS] = 0; // not busy
m_milliseconds = 0;
}
INLINE UINT8 make_bcd(UINT8 data)
{
return ((data / 10) << 4) | (data % 10);
}
//-------------------------------------------------
// device_timer - handler timer events
//-------------------------------------------------
void mm58167_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
m_milliseconds++;
if (m_milliseconds >= 999)
{
advance_seconds();
m_milliseconds = 0;
}
m_regs[R_CNT_MILLISECONDS] = make_bcd(m_milliseconds % 10);
m_regs[R_CNT_HUNDTENTHS] = make_bcd(m_milliseconds / 10);
}
//-------------------------------------------------
// rtc_clock_updated -
//-------------------------------------------------
void mm58167_device::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
{
m_regs[R_CNT_SECONDS] = make_bcd(second); // seconds (BCD)
m_regs[R_CNT_MINUTES] = make_bcd(minute); // minutes (BCD)
m_regs[R_CNT_HOURS] = make_bcd(hour); // hour (BCD)
m_regs[R_CNT_DAYOFWEEK] = make_bcd(day_of_week); // day of the week (BCD)
m_regs[R_CNT_DAYOFMONTH] = make_bcd(day); // day of the month (BCD)
m_regs[R_CNT_MONTH] = make_bcd(month); // month (BCD)
}
READ8_MEMBER(mm58167_device::read)
{
// printf("read reg %x = %02x\n", offset, m_regs[offset]);
return m_regs[offset];
}
WRITE8_MEMBER(mm58167_device::write)
{
// printf("%02x to reg %x\n", data, offset);
if ((offset >= R_RAM_MILLISECONDS) && (offset != R_CTL_IRQSTATUS))
{
m_regs[offset] = data;
}
switch (offset)
{
// any write to this starts at the current time and zero milliseconds
case R_CTL_GOCMD:
m_milliseconds = 0;
break;
case R_CTL_RESETRAM:
if (data == 0xff)
{
for (int i = R_RAM_MILLISECONDS; i < R_CTL_IRQSTATUS; i++)
{
m_regs[i] = 0;
}
}
break;
case R_CTL_IRQCONTROL:
if (data != 0)
{
logerror("MM58167: IRQs not implemented\n");
}
break;
}
}

67
src/emu/machine/mm58167.h Normal file
View File

@ -0,0 +1,67 @@
/**********************************************************************
mm58167.h - National Semiconductor MM58167 real-time clock emulation
license: MAME, BSD-3-Clause, LGPL v2
copyright-holders: R. Belmont
**********************************************************************/
#pragma once
#ifndef __MM58167_H__
#define __MM58167_H__
#include "emu.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_MM58167_IRQ_CALLBACK(_cb) \
devcb = &mm58167_device::set_irq_cb(*device, DEVCB2_##_cb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> mm58167_device
class mm58167_device : public device_t,
public device_rtc_interface
{
public:
// construction/destruction
mm58167_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
template<class _Object> static devcb2_base &set_irq_cb(device_t &device, _Object wr) { return downcast<mm58167_device &>(device).m_irq_w.set_callback(wr); }
devcb2_write_line m_irq_w;
protected:
// device-level overrides
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_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second);
virtual bool rtc_feature_leap_year() { return true; }
private:
int m_regs[32];
int m_milliseconds;
// timers
emu_timer *m_clock_timer;
};
// device type definition
extern const device_type MM58167;
#endif

View File

@ -104,10 +104,14 @@ static MACHINE_CONFIG_START( apple3, apple3_state )
/* fdc */
MCFG_APPLEFDC_ADD("fdc", apple3_fdc_interface)
MCFG_LEGACY_FLOPPY_APPLE_4_DRIVES_ADD(apple3_floppy_interface,1,4)
/* acia */
MCFG_DEVICE_ADD("acia", MOS6551, XTAL_1_8432MHz)
MCFG_MOS6551_TYPE(MOS6551_TYPE_ROCKWELL) // must be Rockwell or the ROM shows "ACIA" and doesn't POST
/* rtc */
MCFG_DEVICE_ADD("rtc", MM58167, XTAL_32_768kHz)
/* via */
MCFG_DEVICE_ADD("via6522_0", VIA6522, 1000000)
MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(apple3_state, apple3_via_0_out_a))

View File

@ -17,6 +17,7 @@
#include "machine/mos6551.h"
#include "machine/6522via.h"
#include "machine/kb3600.h"
#include "machine/mm58167.h"
#include "sound/speaker.h"
#include "sound/dac.h"
@ -45,6 +46,7 @@ public:
m_fdc(*this, "fdc"),
m_ay3600(*this, "ay3600"),
m_a2bus(*this, "a2bus"),
m_rtc(*this, "rtc"),
m_speaker(*this, SPEAKER_TAG),
m_dac(*this, DAC_TAG),
m_kbspecial(*this, "keyb_special")
@ -59,6 +61,7 @@ public:
required_device<applefdc_base_device> m_fdc;
required_device<ay3600_device> m_ay3600;
required_device<a2bus_device> m_a2bus;
required_device<mm58167_device> m_rtc;
required_device<speaker_sound_device> m_speaker;
required_device<dac_device> m_dac;
required_ioport m_kbspecial;

View File

@ -149,6 +149,13 @@ READ8_MEMBER(apple3_state::apple3_c0xx_r)
result = 0x00;
break;
case 0x70: case 0x71: case 0x72: case 0x73:
case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7A: case 0x7B:
case 0x7C: case 0x7D: case 0x7E: case 0x7F:
result = m_rtc->read(space, m_via_0_b);
break;
case 0x90: case 0x91: case 0x92: case 0x93:
case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9a: case 0x9b:
@ -271,6 +278,15 @@ WRITE8_MEMBER(apple3_state::apple3_c0xx_w)
m_flags &= ~(1 << ((offset - 0x50) / 2));
break;
case 0x70: case 0x71: case 0x72: case 0x73:
case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7A: case 0x7B:
case 0x7C: case 0x7D: case 0x7E: case 0x7F:
m_rtc->write(space, m_via_0_b, data);
break;
case 0x90: case 0x91: case 0x92: case 0x93:
case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9a: case 0x9b:

View File

@ -480,6 +480,7 @@ MACHINES += Z80PIO
MACHINES += Z80SIO
MACHINES += Z80STI
MACHINES += Z8536
MACHINES += MM58167
#-------------------------------------------------
# specify available bus cores