mirror of
https://github.com/holub/mame
synced 2025-06-16 09:20:04 +03:00
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:
parent
0c3654a5c9
commit
14c3d33e86
@ -144,7 +144,7 @@ public:
|
||||
m_iwm(*this, "fdc"),
|
||||
m_floppy(*this, "fdc:%d", 0U),
|
||||
m_mackbd(*this, "kbd"),
|
||||
m_rtc(*this,"rtc"),
|
||||
m_rtc(*this, "rtc"),
|
||||
m_screen(*this, "screen"),
|
||||
m_dac(*this, "macdac"),
|
||||
m_filter(*this, "dacfilter"),
|
||||
@ -1182,6 +1182,8 @@ void mac128_state::mac128k(machine_config &config)
|
||||
mac512ke(config);
|
||||
m_ram->set_default_size("128K");
|
||||
|
||||
RTC3430040(config.replace(), m_rtc, 32.768_kHz_XTAL);
|
||||
|
||||
IWM(config.replace(), m_iwm, C7M);
|
||||
m_iwm->phases_cb().set(FUNC(mac128_state::phases_w));
|
||||
m_iwm->devsel_cb().set(FUNC(mac128_state::devsel_w));
|
||||
|
@ -2,27 +2,45 @@
|
||||
// copyright-holders:R. Belmont
|
||||
/***************************************************************************
|
||||
|
||||
macrtc.c - the real-time clock & NVRAM chip used in early 680x0 Macs,
|
||||
Apple part numbers 343-0040 (original) and 343-0042 (with extended PRAM)
|
||||
macrtc.cpp
|
||||
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
|
||||
sophisticated logic block that offloads the low-level serial comms
|
||||
from the CPU, which makes it look quite different to software.
|
||||
Commands and data are sent and received serially, bit 7 first.
|
||||
For reading the chip, the data is valid after the falling edge of the clock.
|
||||
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 "macrtc.h"
|
||||
|
||||
#ifdef MAME_DEBUG
|
||||
#define LOG_RTC 0
|
||||
#else
|
||||
#define LOG_RTC 0
|
||||
#endif
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
#define LOG_COMMANDS (1U << 1)
|
||||
|
||||
//#define VERBOSE (LOG_COMMANDS)
|
||||
#define LOG_OUTPUT_FUNC osd_printf_info
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
enum
|
||||
{
|
||||
RTC_STATE_NORMAL,
|
||||
RTC_STATE_NORMAL = 0,
|
||||
RTC_STATE_WRITE,
|
||||
RTC_STATE_XPCOMMAND,
|
||||
RTC_STATE_XPWRITE
|
||||
@ -33,21 +51,33 @@ enum
|
||||
//**************************************************************************
|
||||
|
||||
// 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
|
||||
//-------------------------------------------------
|
||||
|
||||
rtc3430042_device::rtc3430042_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, RTC3430042, tag, owner, 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, type, tag, owner, clock),
|
||||
device_rtc_interface(mconfig, *this),
|
||||
device_nvram_interface(mconfig, *this),
|
||||
m_is_big_PRAM(hasBigPRAM),
|
||||
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()
|
||||
{
|
||||
m_cko_cb.resolve_safe();
|
||||
@ -66,35 +96,36 @@ void rtc3430042_device::device_start()
|
||||
m_cko = true;
|
||||
|
||||
// state saving
|
||||
save_item(NAME(m_rtc_rTCEnb));
|
||||
save_item(NAME(m_rtc_rTCClk));
|
||||
save_item(NAME(m_rtc_data_byte));
|
||||
save_item(NAME(m_rtc_bit_count));
|
||||
save_item(NAME(m_rtc_data_dir));
|
||||
save_item(NAME(m_rtc_data_out));
|
||||
save_item(NAME(m_rtc_cmd));
|
||||
save_item(NAME(m_rtc_write_protect));
|
||||
save_item(NAME(m_rtc_seconds));
|
||||
save_item(NAME(m_rTCEnb));
|
||||
save_item(NAME(m_rTCClk));
|
||||
save_item(NAME(m_data_byte));
|
||||
save_item(NAME(m_bit_count));
|
||||
save_item(NAME(m_data_dir));
|
||||
save_item(NAME(m_data_out));
|
||||
save_item(NAME(m_cmd));
|
||||
save_item(NAME(m_write_protect));
|
||||
save_item(NAME(m_test_mode));
|
||||
save_item(NAME(m_seconds));
|
||||
save_item(NAME(m_pram));
|
||||
save_item(NAME(m_rtc_xpaddr));
|
||||
save_item(NAME(m_rtc_state));
|
||||
save_item(NAME(m_xpaddr));
|
||||
save_item(NAME(m_state));
|
||||
save_item(NAME(m_data_latch));
|
||||
save_item(NAME(m_cko));
|
||||
}
|
||||
|
||||
void rtc3430042_device::device_reset()
|
||||
{
|
||||
m_rtc_rTCEnb = 0;
|
||||
m_rtc_rTCClk = 0;
|
||||
m_rtc_bit_count = 0;
|
||||
m_rtc_data_dir = 0;
|
||||
m_rtc_data_out = 0;
|
||||
m_rtc_cmd = 0;
|
||||
m_rtc_write_protect = 0;
|
||||
m_rtc_state = 0;
|
||||
m_rTCEnb = 0;
|
||||
m_rTCClk = 0;
|
||||
m_bit_count = 0;
|
||||
m_data_dir = 0;
|
||||
m_data_out = 0;
|
||||
m_cmd = 0;
|
||||
m_write_protect = 0;
|
||||
m_state = 0;
|
||||
|
||||
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_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_min = 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));
|
||||
|
||||
if (LOG_RTC)
|
||||
logerror("second count 0x%lX\n", (unsigned long) seconds);
|
||||
LOGMASKED(LOG_GENERAL, "second count 0x%lX\n", (unsigned long) seconds);
|
||||
|
||||
m_rtc_seconds[0] = seconds & 0xff;
|
||||
m_rtc_seconds[1] = (seconds >> 8) & 0xff;
|
||||
m_rtc_seconds[2] = (seconds >> 16) & 0xff;
|
||||
m_rtc_seconds[3] = (seconds >> 24) & 0xff;
|
||||
m_seconds[0] = seconds & 0xff;
|
||||
m_seconds[1] = (seconds >> 8) & 0xff;
|
||||
m_seconds[2] = (seconds >> 16) & 0xff;
|
||||
m_seconds[3] = (seconds >> 24) & 0xff;
|
||||
}
|
||||
|
||||
/* write the rTCEnb state */
|
||||
/* write the chip enable state */
|
||||
WRITE_LINE_MEMBER( rtc3430042_device::ce_w )
|
||||
{
|
||||
if (state && (! m_rtc_rTCEnb))
|
||||
if (state && (! m_rTCEnb))
|
||||
{
|
||||
/* rTCEnb goes high (inactive) */
|
||||
m_rtc_rTCEnb = 1;
|
||||
m_rTCEnb = 1;
|
||||
/* abort current transmission */
|
||||
m_rtc_data_byte = m_rtc_bit_count = m_rtc_data_dir = m_rtc_data_out = 0;
|
||||
m_rtc_state = RTC_STATE_NORMAL;
|
||||
m_data_byte = m_bit_count = m_data_dir = m_data_out = 0;
|
||||
m_state = RTC_STATE_NORMAL;
|
||||
}
|
||||
else if ((!state) && m_rtc_rTCEnb)
|
||||
else if ((!state) && m_rTCEnb)
|
||||
{
|
||||
/* rTCEnb goes low (active) */
|
||||
m_rtc_rTCEnb = 0;
|
||||
m_rTCEnb = 0;
|
||||
/* abort current transmission */
|
||||
m_rtc_data_byte = m_rtc_bit_count = m_rtc_data_dir = m_rtc_data_out = 0;
|
||||
m_rtc_state = RTC_STATE_NORMAL;
|
||||
m_data_byte = m_bit_count = m_data_dir = m_data_out = 0;
|
||||
m_state = RTC_STATE_NORMAL;
|
||||
}
|
||||
|
||||
m_rtc_rTCEnb = state;
|
||||
m_rTCEnb = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rtc3430042_device::clk_w )
|
||||
{
|
||||
if ((!state) && (m_rtc_rTCClk))
|
||||
if ((!state) && (m_rTCClk))
|
||||
{
|
||||
rtc_shift_data(m_data_latch & 0x01);
|
||||
}
|
||||
|
||||
m_rtc_rTCClk = state;
|
||||
m_rTCClk = state;
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER( rtc3430042_device::data_r )
|
||||
{
|
||||
return m_rtc_data_out;
|
||||
return m_data_out;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rtc3430042_device::data_w )
|
||||
@ -191,184 +219,187 @@ WRITE_LINE_MEMBER( rtc3430042_device::data_w )
|
||||
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)
|
||||
{
|
||||
if (m_rtc_rTCEnb)
|
||||
/* if enable line inactive (high), do nothing */
|
||||
// Chip enable must be asserted for the chip to listen
|
||||
if (m_rTCEnb)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_rtc_data_dir)
|
||||
{ /* RTC -> VIA transmission */
|
||||
m_rtc_data_out = (m_rtc_data_byte >> --m_rtc_bit_count) & 0x01;
|
||||
if (LOG_RTC)
|
||||
logerror("RTC shifted new data %d\n", m_rtc_data_out);
|
||||
// sending data to the host
|
||||
if (m_data_dir)
|
||||
{
|
||||
m_data_out = (m_data_byte >> --m_bit_count) & 0x01;
|
||||
LOGMASKED(LOG_GENERAL, "RTC shifted new data %d\n", m_data_out);
|
||||
}
|
||||
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)
|
||||
{ /* if one byte received, send to command interpreter */
|
||||
rtc_execute_cmd(m_rtc_data_byte);
|
||||
m_bit_count++;
|
||||
if (m_bit_count == 8)
|
||||
{
|
||||
// got a byte, send it to the state machine
|
||||
rtc_execute_cmd(m_data_byte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Executes a command.
|
||||
Called when the first byte after "enable" is received, and when the data byte after a write command
|
||||
is received. */
|
||||
/* Executes a command. Called when the first byte after "enable" is received, and
|
||||
when the data byte after a write command is received. */
|
||||
void rtc3430042_device::rtc_execute_cmd(int data)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (LOG_RTC)
|
||||
printf("rtc_execute_cmd: data=%x, state=%x\n", data, m_rtc_state);
|
||||
LOGMASKED(LOG_COMMANDS, "rtc_execute_cmd: data=%x, state=%x\n", data, m_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);
|
||||
if ((m_rtc_cmd & 0x80) != 0)
|
||||
m_xpaddr = ((m_cmd & 7)<<5) | ((data&0x7c)>>2);
|
||||
if ((m_cmd & 0x80) != 0)
|
||||
{
|
||||
// read command
|
||||
if (LOG_RTC)
|
||||
printf("RTC: Reading extended address %x = %x\n", m_rtc_xpaddr, m_pram[m_rtc_xpaddr]);
|
||||
LOGMASKED(LOG_COMMANDS, "RTC: Reading extended address %x = %x\n", m_xpaddr, m_pram[m_xpaddr]);
|
||||
|
||||
m_rtc_data_dir = 1;
|
||||
m_rtc_data_byte = m_pram[m_rtc_xpaddr];
|
||||
m_rtc_state = RTC_STATE_NORMAL;
|
||||
m_data_dir = 1;
|
||||
m_data_byte = m_pram[m_xpaddr];
|
||||
m_state = RTC_STATE_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// write command
|
||||
m_rtc_state = RTC_STATE_XPWRITE;
|
||||
m_rtc_data_byte = 0;
|
||||
m_rtc_bit_count = 0;
|
||||
m_state = RTC_STATE_XPWRITE;
|
||||
m_data_byte = 0;
|
||||
m_bit_count = 0;
|
||||
}
|
||||
}
|
||||
else if (m_rtc_state == RTC_STATE_XPWRITE)
|
||||
else if (m_state == RTC_STATE_XPWRITE)
|
||||
{
|
||||
if (LOG_RTC)
|
||||
printf("RTC: writing %x to extended address %x\n", data, m_rtc_xpaddr);
|
||||
m_pram[m_rtc_xpaddr] = data;
|
||||
m_rtc_state = RTC_STATE_NORMAL;
|
||||
LOGMASKED(LOG_COMMANDS, "RTC: writing %x to extended address %x\n", data, m_xpaddr);
|
||||
m_pram[m_xpaddr] = data;
|
||||
m_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 */
|
||||
i = (m_rtc_cmd >> 2) & 0x1f;
|
||||
if (m_rtc_write_protect && (i != 13))
|
||||
/* write-protection : only write-protect can be written again */
|
||||
// Register write
|
||||
i = (m_cmd >> 2) & 0x1f;
|
||||
if (m_write_protect && (i != 13))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch(i)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: /* seconds register */
|
||||
case 4: case 5: case 6: case 7: /* ??? (not described in IM III) */
|
||||
{
|
||||
/* after various tries, I assumed m_rtc_seconds[4+i] is mapped to m_rtc_seconds[i] */
|
||||
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
|
||||
}
|
||||
case 0: case 1: case 2: case 3: // seconds register
|
||||
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);
|
||||
m_seconds[i & 3] = m_data_byte;
|
||||
break;
|
||||
|
||||
case 8: case 9: case 10: case 11: /* RAM address $10-$13 */
|
||||
if (LOG_RTC)
|
||||
printf("PRAM write, address = %X, data = %X\n", i, (int) m_rtc_data_byte);
|
||||
m_pram[i] = m_rtc_data_byte;
|
||||
case 8: case 9: case 10: case 11: // PRAM addresses 0x10-0x13
|
||||
LOGMASKED(LOG_COMMANDS, "PRAM write, address = %X, data = %X\n", i, (int)m_data_byte);
|
||||
m_pram[i] = m_data_byte;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
/* Test register - do nothing */
|
||||
if (LOG_RTC)
|
||||
logerror("RTC write to test register, data = %X\n", (int) m_rtc_data_byte);
|
||||
// Test register - resets the seconds counter and increments it on the raw clock (32768 Hz) instead of once a second (not implemented)
|
||||
LOGMASKED(LOG_COMMANDS, "RTC write to test register, data = %X\n", (int)m_data_byte);
|
||||
m_test_mode = BIT(m_data_byte, 7);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
/* Write-protect register */
|
||||
if (LOG_RTC)
|
||||
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;
|
||||
// Write protect - when set, all registers become read-only except this one
|
||||
if (!m_is_big_PRAM)
|
||||
{
|
||||
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;
|
||||
|
||||
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 24: case 25: case 26: case 27:
|
||||
case 28: case 29: case 30: case 31:
|
||||
if (LOG_RTC)
|
||||
printf("PRAM write, address = %X, data = %X\n", i, (int) m_rtc_data_byte);
|
||||
m_pram[i] = m_rtc_data_byte;
|
||||
LOGMASKED(LOG_COMMANDS, "PRAM write, address = %X, data = %X\n", i, (int)m_data_byte);
|
||||
m_pram[i] = m_data_byte;
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// always save this byte to m_rtc_cmd
|
||||
m_rtc_cmd = m_rtc_data_byte;
|
||||
// always save this byte to m_cmd
|
||||
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_rtc_data_byte = 0;
|
||||
m_rtc_bit_count = 0;
|
||||
m_state = RTC_STATE_XPCOMMAND;
|
||||
m_data_byte = 0;
|
||||
m_bit_count = 0;
|
||||
}
|
||||
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 */
|
||||
m_rtc_data_dir = 1;
|
||||
i = (m_rtc_cmd >> 2) & 0x1f;
|
||||
// RTC register read
|
||||
m_data_dir = 1;
|
||||
i = (m_cmd >> 2) & 0x1f;
|
||||
switch(i)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
case 4: case 5: case 6: case 7:
|
||||
m_rtc_data_byte = m_rtc_seconds[i & 3];
|
||||
if (LOG_RTC)
|
||||
printf("RTC clock read, address = %X -> data = %X\n", i, m_rtc_data_byte);
|
||||
m_data_byte = m_seconds[i & 3];
|
||||
LOGMASKED(LOG_COMMANDS, "RTC clock read, address = %X -> data = %X\n", i, m_data_byte);
|
||||
break;
|
||||
|
||||
case 8: case 9: case 10: case 11:
|
||||
if (LOG_RTC)
|
||||
printf("PRAM read, address = %X data = %x\n", i, m_pram[i]);
|
||||
m_rtc_data_byte = m_pram[i];
|
||||
LOGMASKED(LOG_COMMANDS, "PRAM read, address = %X data = %x\n", i, m_pram[i]);
|
||||
m_data_byte = m_pram[i];
|
||||
break;
|
||||
|
||||
case 16: case 17: case 18: case 19:
|
||||
case 20: case 21: case 22: case 23:
|
||||
case 24: case 25: case 26: case 27:
|
||||
case 28: case 29: case 30: case 31:
|
||||
if (LOG_RTC)
|
||||
printf("PRAM read, address = %X data = %x\n", i, m_pram[i]);
|
||||
m_rtc_data_byte = m_pram[i];
|
||||
LOGMASKED(LOG_COMMANDS, "PRAM read, address = %X data = %x\n", i, m_pram[i]);
|
||||
m_data_byte = m_pram[i];
|
||||
break;
|
||||
|
||||
default:
|
||||
if (LOG_RTC)
|
||||
logerror("Unknown RTC read command : %X\n", (int) m_rtc_cmd);
|
||||
m_rtc_data_byte = 0;
|
||||
LOGMASKED(LOG_COMMANDS, "Unknown RTC read command : %X\n", (int)m_cmd);
|
||||
m_data_byte = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Writing an RTC register */
|
||||
/* wait for extra data byte */
|
||||
if (LOG_RTC)
|
||||
logerror("RTC write, waiting for data byte : %X\n", (int) m_rtc_cmd);
|
||||
m_rtc_state = RTC_STATE_WRITE;
|
||||
m_rtc_data_byte = 0;
|
||||
m_rtc_bit_count = 0;
|
||||
// RTC register write - wait for data byte
|
||||
LOGMASKED(LOG_COMMANDS, "RTC write, waiting for data byte : %X\n", (int)m_cmd);
|
||||
m_state = RTC_STATE_WRITE;
|
||||
m_data_byte = 0;
|
||||
m_bit_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -390,3 +421,15 @@ bool rtc3430042_device::nvram_write(util::write_stream &file)
|
||||
size_t actual;
|
||||
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;
|
||||
}
|
||||
|
@ -25,8 +25,11 @@ class rtc3430042_device : public device_t,
|
||||
public device_rtc_interface,
|
||||
public device_nvram_interface
|
||||
{
|
||||
friend class rtc3430040_device;
|
||||
|
||||
public:
|
||||
// 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);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( ce_w );
|
||||
@ -55,35 +58,40 @@ protected:
|
||||
TIMER_CALLBACK_MEMBER(half_seconds_tick);
|
||||
|
||||
private:
|
||||
bool m_is_big_PRAM;
|
||||
|
||||
devcb_write_line m_cko_cb;
|
||||
|
||||
/* state of rTCEnb and rTCClk lines */
|
||||
uint8_t m_rtc_rTCEnb = 0;
|
||||
uint8_t m_rtc_rTCClk = 0;
|
||||
u8 m_rTCEnb = 0;
|
||||
u8 m_rTCClk = 0;
|
||||
|
||||
/* 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 */
|
||||
uint8_t m_rtc_bit_count = 0;
|
||||
u8 m_bit_count = 0;
|
||||
/* 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) */
|
||||
uint8_t m_rtc_data_out = 0;
|
||||
u8 m_data_out = 0;
|
||||
|
||||
/* set to 1 when command in progress */
|
||||
uint8_t m_rtc_cmd = 0;
|
||||
u8 m_cmd = 0;
|
||||
|
||||
/* 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 */
|
||||
uint8_t m_rtc_seconds[/*8*/4]{};
|
||||
u8 m_seconds[/*8*/4]{};
|
||||
/* 20-byte long PRAM, or 256-byte long XPRAM */
|
||||
uint8_t m_pram[256]{};
|
||||
u8 m_pram[256]{};
|
||||
/* current extended address and RTC state */
|
||||
uint8_t m_rtc_xpaddr = 0;
|
||||
uint8_t m_rtc_state = 0;
|
||||
uint8_t m_data_latch = 0;
|
||||
u8 m_xpaddr = 0;
|
||||
u8 m_state = 0;
|
||||
u8 m_data_latch = 0;
|
||||
bool m_cko = false;
|
||||
|
||||
// timers
|
||||
@ -93,8 +101,19 @@ private:
|
||||
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
|
||||
DECLARE_DEVICE_TYPE(RTC3430040, rtc3430040_device)
|
||||
DECLARE_DEVICE_TYPE(RTC3430042, rtc3430042_device)
|
||||
|
||||
#endif // MAME_MACHINE_MACRTC_H
|
||||
|
Loading…
Reference in New Issue
Block a user