macrtc.cpp: Updates [R. Belmont]

- Cleaned up, modernized, converted logging to logmacro.h
- Improved documentation comments
- Supports both the original 343-0040 (Mac 128/512) and the 343-0042-B (Mac II, Apple IIgs) with unique behavior
This commit is contained in:
arbee 2022-12-16 13:41:36 -05:00
parent 0c3654a5c9
commit 14c3d33e86
3 changed files with 230 additions and 166 deletions

View File

@ -144,7 +144,7 @@ public:
m_iwm(*this, "fdc"), m_iwm(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U), m_floppy(*this, "fdc:%d", 0U),
m_mackbd(*this, "kbd"), m_mackbd(*this, "kbd"),
m_rtc(*this,"rtc"), m_rtc(*this, "rtc"),
m_screen(*this, "screen"), m_screen(*this, "screen"),
m_dac(*this, "macdac"), m_dac(*this, "macdac"),
m_filter(*this, "dacfilter"), m_filter(*this, "dacfilter"),
@ -1182,6 +1182,8 @@ void mac128_state::mac128k(machine_config &config)
mac512ke(config); mac512ke(config);
m_ram->set_default_size("128K"); m_ram->set_default_size("128K");
RTC3430040(config.replace(), m_rtc, 32.768_kHz_XTAL);
IWM(config.replace(), m_iwm, C7M); IWM(config.replace(), m_iwm, C7M);
m_iwm->phases_cb().set(FUNC(mac128_state::phases_w)); m_iwm->phases_cb().set(FUNC(mac128_state::phases_w));
m_iwm->devsel_cb().set(FUNC(mac128_state::devsel_w)); m_iwm->devsel_cb().set(FUNC(mac128_state::devsel_w));

View File

@ -2,27 +2,45 @@
// copyright-holders:R. Belmont // copyright-holders:R. Belmont
/*************************************************************************** /***************************************************************************
macrtc.c - the real-time clock & NVRAM chip used in early 680x0 Macs, macrtc.cpp
Apple part numbers 343-0040 (original) and 343-0042 (with extended PRAM) Real-time clock & NVRAM chips used in early 680x0 Macs and the Apple IIgs.
Apple part numbers 343-0040 (original, 20 bytes of PRAM) and 343-0042-B (256 bytes of PRAM).
By R. Belmont, based on previous work by Nathan Woods and Raphael Nabet
The IIgs has this chip also, but the VGC contains a relatively Commands and data are sent and received serially, bit 7 first.
sophisticated logic block that offloads the low-level serial comms For reading the chip, the data is valid after the falling edge of the clock.
from the CPU, which makes it look quite different to software. For writing, the data must be valid before the falling edge of the clock.
The time is the number of seconds since midnight on January 1, 1904.
Commands:
R/W 00x0001 - Seconds (least significant byte)
R/W 00x0101 - Seconds (2nd byte)
R/W 00x1001 - Seconds (3rd byte)
R/W 00x1101 - Seconds (most significant byte)
0 0110001 - Test register
0 0110101 - Write protect bit (343-0040) (When set, only the WP bit itself can be changed)
0 01101xx - Write protect bit (343-0042-B)
R/W 010aa01 - 4 PRAM addresses (aa is the address)
R/W 1aaaa01 - 16 PRAM addresses (aaaa is the address)
R/W 0111aaa - Extended PRAM address (aaa is the sector number. Sectors are 32 bytes)
***************************************************************************/ ***************************************************************************/
#include "emu.h" #include "emu.h"
#include "macrtc.h" #include "macrtc.h"
#ifdef MAME_DEBUG #define LOG_GENERAL (1U << 0)
#define LOG_RTC 0 #define LOG_COMMANDS (1U << 1)
#else
#define LOG_RTC 0 //#define VERBOSE (LOG_COMMANDS)
#endif #define LOG_OUTPUT_FUNC osd_printf_info
#include "logmacro.h"
enum enum
{ {
RTC_STATE_NORMAL, RTC_STATE_NORMAL = 0,
RTC_STATE_WRITE, RTC_STATE_WRITE,
RTC_STATE_XPCOMMAND, RTC_STATE_XPCOMMAND,
RTC_STATE_XPWRITE RTC_STATE_XPWRITE
@ -33,21 +51,33 @@ enum
//************************************************************************** //**************************************************************************
// device type definition // device type definition
DEFINE_DEVICE_TYPE(RTC3430042, rtc3430042_device, "rtc3430042", "Apple 343-0042 clock/PRAM") DEFINE_DEVICE_TYPE(RTC3430040, rtc3430040_device, "rtc3430040", "Apple 343-0040 clock/PRAM")
DEFINE_DEVICE_TYPE(RTC3430042, rtc3430042_device, "rtc3430042", "Apple 343-0042-B clock/PRAM")
//------------------------------------------------- //-------------------------------------------------
// rtc4543_device - constructor // rtc4543_device - constructor
//------------------------------------------------- //-------------------------------------------------
rtc3430042_device::rtc3430042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) rtc3430042_device::rtc3430042_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool hasBigPRAM)
: device_t(mconfig, RTC3430042, tag, owner, clock), : device_t(mconfig, type, tag, owner, clock),
device_rtc_interface(mconfig, *this), device_rtc_interface(mconfig, *this),
device_nvram_interface(mconfig, *this), device_nvram_interface(mconfig, *this),
m_is_big_PRAM(hasBigPRAM),
m_cko_cb(*this) m_cko_cb(*this)
{ {
} }
rtc3430042_device::rtc3430042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: rtc3430042_device(mconfig, RTC3430042, tag, owner, clock, true)
{
}
rtc3430040_device::rtc3430040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: rtc3430042_device(mconfig, RTC3430040, tag, owner, clock, false)
{
}
void rtc3430042_device::device_resolve_objects() void rtc3430042_device::device_resolve_objects()
{ {
m_cko_cb.resolve_safe(); m_cko_cb.resolve_safe();
@ -66,35 +96,36 @@ void rtc3430042_device::device_start()
m_cko = true; m_cko = true;
// state saving // state saving
save_item(NAME(m_rtc_rTCEnb)); save_item(NAME(m_rTCEnb));
save_item(NAME(m_rtc_rTCClk)); save_item(NAME(m_rTCClk));
save_item(NAME(m_rtc_data_byte)); save_item(NAME(m_data_byte));
save_item(NAME(m_rtc_bit_count)); save_item(NAME(m_bit_count));
save_item(NAME(m_rtc_data_dir)); save_item(NAME(m_data_dir));
save_item(NAME(m_rtc_data_out)); save_item(NAME(m_data_out));
save_item(NAME(m_rtc_cmd)); save_item(NAME(m_cmd));
save_item(NAME(m_rtc_write_protect)); save_item(NAME(m_write_protect));
save_item(NAME(m_rtc_seconds)); save_item(NAME(m_test_mode));
save_item(NAME(m_seconds));
save_item(NAME(m_pram)); save_item(NAME(m_pram));
save_item(NAME(m_rtc_xpaddr)); save_item(NAME(m_xpaddr));
save_item(NAME(m_rtc_state)); save_item(NAME(m_state));
save_item(NAME(m_data_latch)); save_item(NAME(m_data_latch));
save_item(NAME(m_cko)); save_item(NAME(m_cko));
} }
void rtc3430042_device::device_reset() void rtc3430042_device::device_reset()
{ {
m_rtc_rTCEnb = 0; m_rTCEnb = 0;
m_rtc_rTCClk = 0; m_rTCClk = 0;
m_rtc_bit_count = 0; m_bit_count = 0;
m_rtc_data_dir = 0; m_data_dir = 0;
m_rtc_data_out = 0; m_data_out = 0;
m_rtc_cmd = 0; m_cmd = 0;
m_rtc_write_protect = 0; m_write_protect = 0;
m_rtc_state = 0; m_state = 0;
ce_w(1); ce_w(1);
m_rtc_state = RTC_STATE_NORMAL; m_state = RTC_STATE_NORMAL;
} }
//------------------------------------------------- //-------------------------------------------------
@ -128,7 +159,7 @@ void rtc3430042_device::rtc_clock_updated(int year, int month, int day, int day_
cur_time.tm_year = year+100; // assumes post-2000 current system time cur_time.tm_year = year+100; // assumes post-2000 current system time
cur_time.tm_isdst = 0; cur_time.tm_isdst = 0;
/* The count starts on 1st January 1904 */ // The count starts on January 1, 1904 at midnight
mac_reference.tm_sec = 0; mac_reference.tm_sec = 0;
mac_reference.tm_min = 0; mac_reference.tm_min = 0;
mac_reference.tm_hour = 0; mac_reference.tm_hour = 0;
@ -139,51 +170,48 @@ void rtc3430042_device::rtc_clock_updated(int year, int month, int day, int day_
seconds = difftime(mktime(&cur_time), mktime(&mac_reference)); seconds = difftime(mktime(&cur_time), mktime(&mac_reference));
if (LOG_RTC) LOGMASKED(LOG_GENERAL, "second count 0x%lX\n", (unsigned long) seconds);
logerror("second count 0x%lX\n", (unsigned long) seconds);
m_rtc_seconds[0] = seconds & 0xff; m_seconds[0] = seconds & 0xff;
m_rtc_seconds[1] = (seconds >> 8) & 0xff; m_seconds[1] = (seconds >> 8) & 0xff;
m_rtc_seconds[2] = (seconds >> 16) & 0xff; m_seconds[2] = (seconds >> 16) & 0xff;
m_rtc_seconds[3] = (seconds >> 24) & 0xff; m_seconds[3] = (seconds >> 24) & 0xff;
} }
/* write the rTCEnb state */ /* write the chip enable state */
WRITE_LINE_MEMBER( rtc3430042_device::ce_w ) WRITE_LINE_MEMBER( rtc3430042_device::ce_w )
{ {
if (state && (! m_rtc_rTCEnb)) if (state && (! m_rTCEnb))
{ {
/* rTCEnb goes high (inactive) */ m_rTCEnb = 1;
m_rtc_rTCEnb = 1;
/* abort current transmission */ /* abort current transmission */
m_rtc_data_byte = m_rtc_bit_count = m_rtc_data_dir = m_rtc_data_out = 0; m_data_byte = m_bit_count = m_data_dir = m_data_out = 0;
m_rtc_state = RTC_STATE_NORMAL; m_state = RTC_STATE_NORMAL;
} }
else if ((!state) && m_rtc_rTCEnb) else if ((!state) && m_rTCEnb)
{ {
/* rTCEnb goes low (active) */ m_rTCEnb = 0;
m_rtc_rTCEnb = 0;
/* abort current transmission */ /* abort current transmission */
m_rtc_data_byte = m_rtc_bit_count = m_rtc_data_dir = m_rtc_data_out = 0; m_data_byte = m_bit_count = m_data_dir = m_data_out = 0;
m_rtc_state = RTC_STATE_NORMAL; m_state = RTC_STATE_NORMAL;
} }
m_rtc_rTCEnb = state; m_rTCEnb = state;
} }
WRITE_LINE_MEMBER( rtc3430042_device::clk_w ) WRITE_LINE_MEMBER( rtc3430042_device::clk_w )
{ {
if ((!state) && (m_rtc_rTCClk)) if ((!state) && (m_rTCClk))
{ {
rtc_shift_data(m_data_latch & 0x01); rtc_shift_data(m_data_latch & 0x01);
} }
m_rtc_rTCClk = state; m_rTCClk = state;
} }
READ_LINE_MEMBER( rtc3430042_device::data_r ) READ_LINE_MEMBER( rtc3430042_device::data_r )
{ {
return m_rtc_data_out; return m_data_out;
} }
WRITE_LINE_MEMBER( rtc3430042_device::data_w ) WRITE_LINE_MEMBER( rtc3430042_device::data_w )
@ -191,184 +219,187 @@ WRITE_LINE_MEMBER( rtc3430042_device::data_w )
m_data_latch = state; m_data_latch = state;
} }
/* shift data (called on rTCClk high-to-low transition (?)) */ /* shift data (called on rTCClk high-to-low transition) */
void rtc3430042_device::rtc_shift_data(int data) void rtc3430042_device::rtc_shift_data(int data)
{ {
if (m_rtc_rTCEnb) // Chip enable must be asserted for the chip to listen
/* if enable line inactive (high), do nothing */ if (m_rTCEnb)
{
return; return;
}
if (m_rtc_data_dir) // sending data to the host
{ /* RTC -> VIA transmission */ if (m_data_dir)
m_rtc_data_out = (m_rtc_data_byte >> --m_rtc_bit_count) & 0x01; {
if (LOG_RTC) m_data_out = (m_data_byte >> --m_bit_count) & 0x01;
logerror("RTC shifted new data %d\n", m_rtc_data_out); LOGMASKED(LOG_GENERAL, "RTC shifted new data %d\n", m_data_out);
} }
else else
{ /* VIA -> RTC transmission */ {
m_rtc_data_byte = (m_rtc_data_byte << 1) | (data ? 1 : 0); // receiving data from the host
m_data_byte = (m_data_byte << 1) | (data ? 1 : 0);
if (++m_rtc_bit_count == 8) m_bit_count++;
{ /* if one byte received, send to command interpreter */ if (m_bit_count == 8)
rtc_execute_cmd(m_rtc_data_byte); {
// got a byte, send it to the state machine
rtc_execute_cmd(m_data_byte);
} }
} }
} }
/* Executes a command. /* Executes a command. Called when the first byte after "enable" is received, and
Called when the first byte after "enable" is received, and when the data byte after a write command when the data byte after a write command is received. */
is received. */
void rtc3430042_device::rtc_execute_cmd(int data) void rtc3430042_device::rtc_execute_cmd(int data)
{ {
int i; int i;
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "rtc_execute_cmd: data=%x, state=%x\n", data, m_state);
printf("rtc_execute_cmd: data=%x, state=%x\n", data, m_rtc_state);
if (m_rtc_state == RTC_STATE_XPCOMMAND) if (m_state == RTC_STATE_XPCOMMAND)
{ {
m_rtc_xpaddr = ((m_rtc_cmd & 7)<<5) | ((data&0x7c)>>2); m_xpaddr = ((m_cmd & 7)<<5) | ((data&0x7c)>>2);
if ((m_rtc_cmd & 0x80) != 0) if ((m_cmd & 0x80) != 0)
{ {
// read command // read command
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "RTC: Reading extended address %x = %x\n", m_xpaddr, m_pram[m_xpaddr]);
printf("RTC: Reading extended address %x = %x\n", m_rtc_xpaddr, m_pram[m_rtc_xpaddr]);
m_rtc_data_dir = 1; m_data_dir = 1;
m_rtc_data_byte = m_pram[m_rtc_xpaddr]; m_data_byte = m_pram[m_xpaddr];
m_rtc_state = RTC_STATE_NORMAL; m_state = RTC_STATE_NORMAL;
} }
else else
{ {
// write command // write command
m_rtc_state = RTC_STATE_XPWRITE; m_state = RTC_STATE_XPWRITE;
m_rtc_data_byte = 0; m_data_byte = 0;
m_rtc_bit_count = 0; m_bit_count = 0;
} }
} }
else if (m_rtc_state == RTC_STATE_XPWRITE) else if (m_state == RTC_STATE_XPWRITE)
{ {
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "RTC: writing %x to extended address %x\n", data, m_xpaddr);
printf("RTC: writing %x to extended address %x\n", data, m_rtc_xpaddr); m_pram[m_xpaddr] = data;
m_pram[m_rtc_xpaddr] = data; m_state = RTC_STATE_NORMAL;
m_rtc_state = RTC_STATE_NORMAL;
} }
else if (m_rtc_state == RTC_STATE_WRITE) else if (m_state == RTC_STATE_WRITE)
{ {
m_rtc_state = RTC_STATE_NORMAL; m_state = RTC_STATE_NORMAL;
/* Writing an RTC register */ // Register write
i = (m_rtc_cmd >> 2) & 0x1f; i = (m_cmd >> 2) & 0x1f;
if (m_rtc_write_protect && (i != 13)) if (m_write_protect && (i != 13))
/* write-protection : only write-protect can be written again */ {
return; return;
}
switch(i) switch(i)
{ {
case 0: case 1: case 2: case 3: /* seconds register */ case 0: case 1: case 2: case 3: // seconds register
case 4: case 5: case 6: case 7: /* ??? (not described in IM III) */ case 4: case 5: case 6: case 7: // bit 4 is don't care
{ LOGMASKED(LOG_COMMANDS, "RTC clock write, address = %X, data = %X\n", i, (int)m_data_byte);
/* after various tries, I assumed m_rtc_seconds[4+i] is mapped to m_rtc_seconds[i] */ m_seconds[i & 3] = m_data_byte;
if (LOG_RTC)
logerror("RTC clock write, address = %X, data = %X\n", i, (int) m_rtc_data_byte);
m_rtc_seconds[i & 3] = m_rtc_data_byte;
// TODO: call the base class's time set here
}
break; break;
case 8: case 9: case 10: case 11: /* RAM address $10-$13 */ case 8: case 9: case 10: case 11: // PRAM addresses 0x10-0x13
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "PRAM write, address = %X, data = %X\n", i, (int)m_data_byte);
printf("PRAM write, address = %X, data = %X\n", i, (int) m_rtc_data_byte); m_pram[i] = m_data_byte;
m_pram[i] = m_rtc_data_byte;
break; break;
case 12: case 12:
/* Test register - do nothing */ // Test register - resets the seconds counter and increments it on the raw clock (32768 Hz) instead of once a second (not implemented)
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "RTC write to test register, data = %X\n", (int)m_data_byte);
logerror("RTC write to test register, data = %X\n", (int) m_rtc_data_byte); m_test_mode = BIT(m_data_byte, 7);
break; break;
case 13: case 13:
/* Write-protect register */ // Write protect - when set, all registers become read-only except this one
if (LOG_RTC) if (!m_is_big_PRAM)
printf("RTC write to write-protect register, data = %X\n", (int) m_rtc_data_byte&0x80); {
m_rtc_write_protect = (m_rtc_data_byte & 0x80) ? true : false; if (m_cmd == 0x35) // b00110101 for 343-0040
{
LOGMASKED(LOG_COMMANDS, "RTC write to write-protect register, data = %X\n", (int)m_data_byte & 0x80);
m_write_protect = BIT(m_data_byte, 7);
}
else
{
logerror("macrtc: 343-0040 illegal write protect command %02x\n", m_cmd);
}
}
else
{
LOGMASKED(LOG_COMMANDS, "RTC write to write-protect register, data = %X\n", (int)m_data_byte & 0x80);
m_write_protect = BIT(m_data_byte, 7);
}
break; break;
case 16: case 17: case 18: case 19: /* RAM address $00-$0f */ case 16: case 17: case 18: case 19: // PRAM addresses 0x00-0x0f
case 20: case 21: case 22: case 23: case 20: case 21: case 22: case 23:
case 24: case 25: case 26: case 27: case 24: case 25: case 26: case 27:
case 28: case 29: case 30: case 31: case 28: case 29: case 30: case 31:
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "PRAM write, address = %X, data = %X\n", i, (int)m_data_byte);
printf("PRAM write, address = %X, data = %X\n", i, (int) m_rtc_data_byte); m_pram[i] = m_data_byte;
m_pram[i] = m_rtc_data_byte;
break; break;
default: default:
printf("Unknown RTC write command : %X, data = %d\n", (int) m_rtc_cmd, (int) m_rtc_data_byte); LOGMASKED(LOG_COMMANDS, "Unknown RTC write command : %X, data = %d\n", (int)m_cmd, (int)m_data_byte);
break; break;
} }
} }
else else
{ {
// always save this byte to m_rtc_cmd // always save this byte to m_cmd
m_rtc_cmd = m_rtc_data_byte; m_cmd = m_data_byte;
if ((m_rtc_cmd & 0x78) == 0x38) // extended command if ((m_cmd & 0x78) == 0x38) // extended command
{ {
m_rtc_state = RTC_STATE_XPCOMMAND; m_state = RTC_STATE_XPCOMMAND;
m_rtc_data_byte = 0; m_data_byte = 0;
m_rtc_bit_count = 0; m_bit_count = 0;
} }
else else
{ {
if (m_rtc_cmd & 0x80) if (m_cmd & 0x80)
{ {
m_rtc_state = RTC_STATE_NORMAL; m_state = RTC_STATE_NORMAL;
/* Reading an RTC register */ // RTC register read
m_rtc_data_dir = 1; m_data_dir = 1;
i = (m_rtc_cmd >> 2) & 0x1f; i = (m_cmd >> 2) & 0x1f;
switch(i) switch(i)
{ {
case 0: case 1: case 2: case 3: case 0: case 1: case 2: case 3:
case 4: case 5: case 6: case 7: case 4: case 5: case 6: case 7:
m_rtc_data_byte = m_rtc_seconds[i & 3]; m_data_byte = m_seconds[i & 3];
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "RTC clock read, address = %X -> data = %X\n", i, m_data_byte);
printf("RTC clock read, address = %X -> data = %X\n", i, m_rtc_data_byte);
break; break;
case 8: case 9: case 10: case 11: case 8: case 9: case 10: case 11:
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "PRAM read, address = %X data = %x\n", i, m_pram[i]);
printf("PRAM read, address = %X data = %x\n", i, m_pram[i]); m_data_byte = m_pram[i];
m_rtc_data_byte = m_pram[i];
break; break;
case 16: case 17: case 18: case 19: case 16: case 17: case 18: case 19:
case 20: case 21: case 22: case 23: case 20: case 21: case 22: case 23:
case 24: case 25: case 26: case 27: case 24: case 25: case 26: case 27:
case 28: case 29: case 30: case 31: case 28: case 29: case 30: case 31:
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "PRAM read, address = %X data = %x\n", i, m_pram[i]);
printf("PRAM read, address = %X data = %x\n", i, m_pram[i]); m_data_byte = m_pram[i];
m_rtc_data_byte = m_pram[i];
break; break;
default: default:
if (LOG_RTC) LOGMASKED(LOG_COMMANDS, "Unknown RTC read command : %X\n", (int)m_cmd);
logerror("Unknown RTC read command : %X\n", (int) m_rtc_cmd); m_data_byte = 0;
m_rtc_data_byte = 0;
break; break;
} }
} }
else else
{ {
/* Writing an RTC register */ // RTC register write - wait for data byte
/* wait for extra data byte */ LOGMASKED(LOG_COMMANDS, "RTC write, waiting for data byte : %X\n", (int)m_cmd);
if (LOG_RTC) m_state = RTC_STATE_WRITE;
logerror("RTC write, waiting for data byte : %X\n", (int) m_rtc_cmd); m_data_byte = 0;
m_rtc_state = RTC_STATE_WRITE; m_bit_count = 0;
m_rtc_data_byte = 0;
m_rtc_bit_count = 0;
} }
} }
} }
@ -390,3 +421,15 @@ bool rtc3430042_device::nvram_write(util::write_stream &file)
size_t actual; size_t actual;
return !file.write(m_pram, 0x100, actual) && actual == 0x100; return !file.write(m_pram, 0x100, actual) && actual == 0x100;
} }
bool rtc3430040_device::nvram_read(util::read_stream &file)
{
size_t actual;
return !file.read(m_pram, 20, actual) && actual == 20;
}
bool rtc3430040_device::nvram_write(util::write_stream &file)
{
size_t actual;
return !file.write(m_pram, 20, actual) && actual == 20;
}

View File

@ -25,8 +25,11 @@ class rtc3430042_device : public device_t,
public device_rtc_interface, public device_rtc_interface,
public device_nvram_interface public device_nvram_interface
{ {
friend class rtc3430040_device;
public: public:
// construction/destruction // construction/destruction
rtc3430042_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool hasBigPRAM);
rtc3430042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); rtc3430042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_WRITE_LINE_MEMBER( ce_w ); DECLARE_WRITE_LINE_MEMBER( ce_w );
@ -55,35 +58,40 @@ protected:
TIMER_CALLBACK_MEMBER(half_seconds_tick); TIMER_CALLBACK_MEMBER(half_seconds_tick);
private: private:
bool m_is_big_PRAM;
devcb_write_line m_cko_cb; devcb_write_line m_cko_cb;
/* state of rTCEnb and rTCClk lines */ /* state of rTCEnb and rTCClk lines */
uint8_t m_rtc_rTCEnb = 0; u8 m_rTCEnb = 0;
uint8_t m_rtc_rTCClk = 0; u8 m_rTCClk = 0;
/* serial transmit/receive register : bits are shifted in/out of this byte */ /* serial transmit/receive register : bits are shifted in/out of this byte */
uint8_t m_rtc_data_byte = 0; u8 m_data_byte = 0;
/* serial transmitted/received bit count */ /* serial transmitted/received bit count */
uint8_t m_rtc_bit_count = 0; u8 m_bit_count = 0;
/* direction of the current transfer (0 : VIA->RTC, 1 : RTC->VIA) */ /* direction of the current transfer (0 : VIA->RTC, 1 : RTC->VIA) */
uint8_t m_rtc_data_dir = 0; u8 m_data_dir = 0;
/* when rtc_data_dir == 1, state of rTCData as set by RTC (-> data bit seen by VIA) */ /* when rtc_data_dir == 1, state of rTCData as set by RTC (-> data bit seen by VIA) */
uint8_t m_rtc_data_out = 0; u8 m_data_out = 0;
/* set to 1 when command in progress */ /* set to 1 when command in progress */
uint8_t m_rtc_cmd = 0; u8 m_cmd = 0;
/* write protect flag */ /* write protect flag */
uint8_t m_rtc_write_protect = 0; u8 m_write_protect = 0;
// test mode flag
u8 m_test_mode = 0;
/* internal seconds register */ /* internal seconds register */
uint8_t m_rtc_seconds[/*8*/4]{}; u8 m_seconds[/*8*/4]{};
/* 20-byte long PRAM, or 256-byte long XPRAM */ /* 20-byte long PRAM, or 256-byte long XPRAM */
uint8_t m_pram[256]{}; u8 m_pram[256]{};
/* current extended address and RTC state */ /* current extended address and RTC state */
uint8_t m_rtc_xpaddr = 0; u8 m_xpaddr = 0;
uint8_t m_rtc_state = 0; u8 m_state = 0;
uint8_t m_data_latch = 0; u8 m_data_latch = 0;
bool m_cko = false; bool m_cko = false;
// timers // timers
@ -93,8 +101,19 @@ private:
void rtc_execute_cmd(int data); void rtc_execute_cmd(int data);
}; };
class rtc3430040_device: public rtc3430042_device
{
public:
rtc3430040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual bool nvram_read(util::read_stream &file) override;
virtual bool nvram_write(util::write_stream &file) override;
};
// device type definition // device type definition
DECLARE_DEVICE_TYPE(RTC3430040, rtc3430040_device)
DECLARE_DEVICE_TYPE(RTC3430042, rtc3430042_device) DECLARE_DEVICE_TYPE(RTC3430042, rtc3430042_device)
#endif // MAME_MACHINE_MACRTC_H #endif // MAME_MACHINE_MACRTC_H