mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
ds1215: modernize and complete emulation
* rename previous ds1315 to earlier/original ds1215 device * support both ds1215 and transparent access methods * implement rtc and nvram interfaces * support updating registers
This commit is contained in:
parent
ab34107f9f
commit
2da636bb21
@ -1170,13 +1170,13 @@ end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/ds1315.h,MACHINES["DS1315"] = true
|
||||
--@src/devices/machine/ds1215.h,MACHINES["DS1215"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["DS1315"]~=null) then
|
||||
if (MACHINES["DS1215"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/ds1315.cpp",
|
||||
MAME_DIR .. "src/devices/machine/ds1315.h",
|
||||
MAME_DIR .. "src/devices/machine/ds1215.cpp",
|
||||
MAME_DIR .. "src/devices/machine/ds1215.h",
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -33,8 +33,8 @@ void bbc_stlrtc_device::device_add_mconfig(machine_config &config)
|
||||
|
||||
void bbc_pmsrtc_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
/* Dallas DS1216 SmartWatch RAM */
|
||||
DS1315(config, m_rtc, 0);
|
||||
/* Dallas DS1216 SmartWatch ROM */
|
||||
DS1216E(config, m_rtc);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
@ -107,18 +107,10 @@ uint8_t bbc_pmsrtc_device::read(offs_t offset)
|
||||
{
|
||||
uint8_t data = get_rom_base()[offset & 0x1fff];
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
data |= m_rtc->read_0();
|
||||
break;
|
||||
case 0x01:
|
||||
data |= m_rtc->read_1();
|
||||
break;
|
||||
case 0x04:
|
||||
if (m_rtc->chip_enable())
|
||||
data = m_rtc->read_data() & 0x01;
|
||||
break;
|
||||
}
|
||||
if (m_rtc->ceo_r())
|
||||
data = m_rtc->read(offset);
|
||||
else
|
||||
m_rtc->read(offset);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include "slot.h"
|
||||
#include "machine/mc146818.h"
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/ds1215.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
@ -62,7 +62,7 @@ protected:
|
||||
virtual uint8_t read(offs_t offset) override;
|
||||
|
||||
private:
|
||||
required_device<ds1315_device> m_rtc;
|
||||
required_device<ds1216e_device> m_rtc;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
@ -78,7 +78,6 @@
|
||||
#include "meb_intrf.h"
|
||||
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/input_merger.h"
|
||||
#include "machine/msm6242.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
|
@ -4,9 +4,6 @@
|
||||
Dobbertin Smartwatch
|
||||
|
||||
Created: 23/2/2015
|
||||
|
||||
TODO: setting the time (requires the DS1315 core to be able to do this,
|
||||
at the moment it just reads the current time)
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
@ -21,8 +18,7 @@ DEFINE_DEVICE_TYPE(CPC_SMARTWATCH, cpc_smartwatch_device, "cpc_smartwatch", "Dob
|
||||
|
||||
void cpc_smartwatch_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
DS1315(config, m_rtc, 0);
|
||||
// no pass-through (?)
|
||||
DS1216E(config, m_rtc);
|
||||
}
|
||||
|
||||
|
||||
@ -63,26 +59,17 @@ void cpc_smartwatch_device::device_start()
|
||||
void cpc_smartwatch_device::device_reset()
|
||||
{
|
||||
address_space &space = m_slot->cpu().space(AS_PROGRAM);
|
||||
space.install_read_handler(0xc000,0xc001, read8sm_delegate(*this, FUNC(cpc_smartwatch_device::rtc_w)));
|
||||
space.install_read_handler(0xc004,0xc004, read8smo_delegate(*this, FUNC(cpc_smartwatch_device::rtc_r)));
|
||||
// FIXME: should cover the whole ROM address decode range
|
||||
space.install_read_handler(0xc000,0xc004, read8sm_delegate(*this, FUNC(cpc_smartwatch_device::rtc_r)));
|
||||
m_bank = membank(":bank7");
|
||||
}
|
||||
|
||||
uint8_t cpc_smartwatch_device::rtc_w(offs_t offset)
|
||||
uint8_t cpc_smartwatch_device::rtc_r(offs_t offset)
|
||||
{
|
||||
uint8_t* bank = (uint8_t*)m_bank->base();
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if(offset & 1)
|
||||
m_rtc->read_1();
|
||||
else
|
||||
m_rtc->read_0();
|
||||
}
|
||||
return bank[offset & 1];
|
||||
}
|
||||
|
||||
uint8_t cpc_smartwatch_device::rtc_r()
|
||||
{
|
||||
uint8_t* bank = (uint8_t*)m_bank->base();
|
||||
return (bank[4] & 0xfe) | (m_rtc->read_data() & 0x01);
|
||||
if (m_rtc->ceo_r())
|
||||
return m_rtc->read(offset);
|
||||
else
|
||||
m_rtc->read(offset);
|
||||
return bank[offset];
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "cpcexp.h"
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/ds1215.h"
|
||||
|
||||
class cpc_smartwatch_device : public device_t, public device_cpc_expansion_card_interface
|
||||
{
|
||||
@ -23,8 +23,7 @@ public:
|
||||
// construction/destruction
|
||||
cpc_smartwatch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
uint8_t rtc_w(offs_t offset);
|
||||
uint8_t rtc_r();
|
||||
uint8_t rtc_r(offs_t offset);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -38,7 +37,7 @@ protected:
|
||||
private:
|
||||
cpc_expansion_slot_device *m_slot;
|
||||
|
||||
required_device<ds1315_device> m_rtc;
|
||||
required_device<ds1216e_device> m_rtc;
|
||||
memory_bank* m_bank;
|
||||
};
|
||||
|
||||
|
@ -73,17 +73,13 @@ void vme_mvme181_card_device::device_start()
|
||||
m_cpu->space(AS_PROGRAM).install_read_tap(0xff820000, 0xff82001f, "rtc",
|
||||
[this](offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
if (!m_rtc->chip_enable())
|
||||
if (ACCESSING_BITS_24_31)
|
||||
{
|
||||
if (BIT(offset, 2))
|
||||
m_rtc->read_1();
|
||||
if (m_rtc->ceo_r())
|
||||
data = (data & 0x00ffffffU) | u32(m_rtc->read(offset >> 2)) << 24;
|
||||
else
|
||||
m_rtc->read_0();
|
||||
m_rtc->read(offset >> 2);
|
||||
}
|
||||
else if (BIT(offset, 4))
|
||||
data = u32(m_rtc->read_data()) << 24;
|
||||
else
|
||||
m_rtc->write_data(BIT(offset, 2));
|
||||
});
|
||||
}
|
||||
|
||||
@ -102,7 +98,7 @@ void vme_mvme181_card_device::device_add_mconfig(machine_config &config)
|
||||
MC88200(config, m_mmu[0], 40_MHz_XTAL / 2, 0x7e).set_mbus(m_cpu, AS_PROGRAM);
|
||||
MC88200(config, m_mmu[1], 40_MHz_XTAL / 2, 0x7f).set_mbus(m_cpu, AS_PROGRAM);
|
||||
|
||||
DS1315(config, m_rtc, 0); // DS1216
|
||||
DS1216E(config, m_rtc);
|
||||
|
||||
SCN2681(config, m_duart, 3.6864_MHz_XTAL); // SCC68692C1A44
|
||||
m_duart->irq_cb().set(FUNC(vme_mvme181_card_device::irq_w<6>));
|
||||
|
@ -7,7 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "cpu/m88000/m88000.h"
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/ds1215.h"
|
||||
#include "machine/mc68681.h"
|
||||
#include "machine/mc88200.h"
|
||||
|
||||
@ -37,7 +37,7 @@ private:
|
||||
required_device<mc88100_device> m_cpu;
|
||||
required_device_array<mc88200_device, 2> m_mmu;
|
||||
|
||||
required_device<ds1315_device> m_rtc;
|
||||
required_device<ds1216e_device> m_rtc;
|
||||
required_device<scn2681_device> m_duart;
|
||||
required_device_array<rs232_port_device, 2> m_serial;
|
||||
|
||||
|
350
src/devices/machine/ds1215.cpp
Normal file
350
src/devices/machine/ds1215.cpp
Normal file
@ -0,0 +1,350 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* Dallas Semiconductor DS1215 Phantom Time Chip
|
||||
*
|
||||
* Sources:
|
||||
* - Dallas Semiconductor 1992-1993 Product Data Book
|
||||
* - Dallas Semiconductor DS1215 Phantom Time Chip, Copyright 1997 Dallas Semiconductor Corporation
|
||||
*
|
||||
* The DS1215 is an integrated circuit which can be optionally coupled with a
|
||||
* CMOS static RAM. Its nonvolatile memory control functions may be enabled or
|
||||
* disabled through a dedicated input line. This device does not have any
|
||||
* address input lines, and is accessed using its chip enable input (/CEI),
|
||||
* output enable (/OE) and write enable (/WE) inputs. Data is input or output
|
||||
* on dedicated D and Q lines. DS1315 is a drop-in replacement for the DS1215,
|
||||
* differing only in offering 3.3V operation and expanded temperature range.
|
||||
*
|
||||
* The DS1216 SmartWatch/RAM and SmartWatch/ROM devices are DIP sockets with an
|
||||
* integrated quartz crystal, lithium battery and CMOS watch function. The
|
||||
* internal operation of these devices is identical to the DS1215, however the
|
||||
* access method varies between SmartWatch/RAM and SmartWatch/ROM device types.
|
||||
* The RAM type operates identically to the DS1215, while the ROM type supports
|
||||
* a "read-only" access mechanism using address lines A0 and A2.
|
||||
*
|
||||
* Address line A2 is treated as an active-low write enable input, while A0 is
|
||||
* used for the input data bit when data is being written to the device. When
|
||||
* the device is being read, data output is available on D0.
|
||||
*
|
||||
* TODO:
|
||||
* - DS124xY variants
|
||||
*/
|
||||
/*
|
||||
* Implementation Notes
|
||||
* --------------------
|
||||
* The ceo() callback and ceo_r() provide access to the active-low chip enable
|
||||
* output (/CEO) signal, which may be used to enable or disable access to a RAM
|
||||
* or ROM device which shares the same address decode output. /CEO is negated
|
||||
* during the 64 cycles following a successful pattern recognition sequence.
|
||||
*
|
||||
* The ds1216e_device::read(offs_t offset) handler implements the SmartWatch/ROM
|
||||
* interface, decoding the offset as described above to provide both read and
|
||||
* write access to the chip. ds1215_device should be used for DS1215/DS1315 and
|
||||
* DS1216 SmartWatch/RAM variants.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ds1215.h"
|
||||
|
||||
#define VERBOSE (LOG_GENERAL)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(DS1215, ds1215_device, "ds1215", "Dallas Semiconductor DS1215 Phantom Time Chip")
|
||||
DEFINE_DEVICE_TYPE(DS1216E, ds1216e_device, "ds1216e", "Dallas Semiconductor DS1216E SmartWatch/ROM")
|
||||
|
||||
enum mode : u8
|
||||
{
|
||||
MODE_IDLE,
|
||||
MODE_MATCH,
|
||||
MODE_DATA,
|
||||
};
|
||||
|
||||
enum reg3_mask : u8
|
||||
{
|
||||
REG3_12 = 0x80, // enable 12 hour time
|
||||
REG3_PM = 0x20, // AM/PM flag (1=PM)
|
||||
};
|
||||
enum reg4_mask : u8
|
||||
{
|
||||
REG4_RST = 0x10, // disable reset
|
||||
REG4_OSC = 0x20, // disable oscillator
|
||||
};
|
||||
|
||||
ds1215_device_base::ds1215_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_nvram_interface(mconfig, *this)
|
||||
, device_rtc_interface(mconfig, *this)
|
||||
, m_ceo(*this)
|
||||
, m_timer(nullptr)
|
||||
, m_mode(MODE_IDLE)
|
||||
, m_count(0)
|
||||
, m_reg{}
|
||||
, m_ceo_state(false)
|
||||
{
|
||||
}
|
||||
|
||||
ds1215_device::ds1215_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: ds1215_device_base(mconfig, DS1215, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
ds1216e_device::ds1216e_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
|
||||
: ds1215_device_base(mconfig, DS1216E, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void ds1215_device_base::device_start()
|
||||
{
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_count));
|
||||
save_item(NAME(m_reg));
|
||||
save_item(NAME(m_ceo_state));
|
||||
|
||||
m_timer = timer_alloc(FUNC(ds1215_device::timer), this);
|
||||
|
||||
update_ceo();
|
||||
}
|
||||
|
||||
void ds1215_device_base::device_reset()
|
||||
{
|
||||
if (!(m_reg[4] & REG4_RST))
|
||||
{
|
||||
m_mode = MODE_IDLE;
|
||||
m_count = 0;
|
||||
|
||||
update_ceo();
|
||||
}
|
||||
|
||||
m_timer->adjust(attotime::from_msec(10), 0, attotime::from_msec(10));
|
||||
}
|
||||
|
||||
bool ds1215_device_base::nvram_read(util::read_stream &file)
|
||||
{
|
||||
auto const [err, actual] = util::read(file, &m_reg[0], std::size(m_reg));
|
||||
return !err && (actual == std::size(m_reg));
|
||||
}
|
||||
|
||||
bool ds1215_device_base::nvram_write(util::write_stream &file)
|
||||
{
|
||||
auto const [err, actual] = util::write(file, &m_reg[0], std::size(m_reg));
|
||||
return !err;
|
||||
}
|
||||
|
||||
void ds1215_device_base::nvram_default()
|
||||
{
|
||||
m_reg[0] = 0; // second/100 = 0
|
||||
m_reg[1] = 0; // second = 0
|
||||
m_reg[2] = 0; // minute = 0
|
||||
m_reg[3] = 0; // 24 hour time, hour = 0
|
||||
m_reg[4] = 1; // enable oscillator, enable reset, day of week = 1
|
||||
m_reg[5] = 1; // day of month = 1
|
||||
m_reg[6] = 1; // month = 1
|
||||
m_reg[7] = 0; // year = 0
|
||||
}
|
||||
|
||||
void ds1215_device_base::rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second)
|
||||
{
|
||||
m_reg[0] = 0; // always zero second/100
|
||||
m_reg[1] = convert_to_bcd(second);
|
||||
m_reg[2] = convert_to_bcd(minute);
|
||||
m_reg[3] &= REG3_12;
|
||||
if (m_reg[3] & REG3_12)
|
||||
{
|
||||
// adjust for PM
|
||||
if (hour > 11)
|
||||
{
|
||||
m_reg[3] |= REG3_PM;
|
||||
hour -= 12;
|
||||
}
|
||||
|
||||
m_reg[3] |= convert_to_bcd(hour ? hour : 12);
|
||||
}
|
||||
else
|
||||
// 24 hour time
|
||||
m_reg[3] |= convert_to_bcd(hour);
|
||||
m_reg[4] = (m_reg[4] & (REG4_OSC | REG4_RST)) | convert_to_bcd(day_of_week);
|
||||
m_reg[5] = convert_to_bcd(day);
|
||||
m_reg[6] = convert_to_bcd(month);
|
||||
m_reg[7] = convert_to_bcd(year);
|
||||
}
|
||||
|
||||
u8 ds1215_device_base::read_bit()
|
||||
{
|
||||
u8 data = 0;
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case MODE_IDLE:
|
||||
// first read starts pattern recognition
|
||||
LOG("pattern recognition started\n");
|
||||
m_mode = MODE_MATCH;
|
||||
m_count = 0;
|
||||
break;
|
||||
|
||||
case MODE_MATCH:
|
||||
// read during match aborts sequence
|
||||
LOG("pattern recognition aborted\n");
|
||||
m_mode = MODE_IDLE;
|
||||
m_count = 0;
|
||||
break;
|
||||
|
||||
case MODE_DATA:
|
||||
data = BIT(m_reg[m_count >> 3], m_count & 7);
|
||||
if (m_count == 63)
|
||||
{
|
||||
LOG("data read completed\n");
|
||||
|
||||
m_mode = MODE_IDLE;
|
||||
m_count = 0;
|
||||
|
||||
update_ceo();
|
||||
}
|
||||
else
|
||||
m_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void ds1215_device_base::write_bit(u8 data)
|
||||
{
|
||||
static constexpr u8 pattern[] = { 0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c };
|
||||
|
||||
switch (m_mode)
|
||||
{
|
||||
case MODE_IDLE:
|
||||
break;
|
||||
|
||||
case MODE_MATCH:
|
||||
if (BIT(pattern[m_count >> 3], m_count & 7) == (data & 1))
|
||||
{
|
||||
// match, check if finished
|
||||
if (m_count == 63)
|
||||
{
|
||||
LOG("pattern recognition completed\n");
|
||||
m_mode = MODE_DATA;
|
||||
m_count = 0;
|
||||
|
||||
update_ceo();
|
||||
}
|
||||
else
|
||||
m_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no match, abort sequence
|
||||
LOG("pattern recognition aborted\n");
|
||||
m_mode = MODE_IDLE;
|
||||
m_count = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_DATA:
|
||||
if (data & 1)
|
||||
m_reg[m_count >> 3] |= 1U << (m_count & 7);
|
||||
else
|
||||
m_reg[m_count >> 3] &= ~(1U << (m_count & 7));
|
||||
|
||||
if (m_count == 63)
|
||||
{
|
||||
LOG("data write completed\n");
|
||||
|
||||
// clear reserved bits
|
||||
m_reg[1] &= 0x7f;
|
||||
m_reg[2] &= 0x7f;
|
||||
m_reg[3] &= 0xbf;
|
||||
m_reg[4] &= 0x37;
|
||||
m_reg[5] &= 0x3f;
|
||||
m_reg[6] &= 0x1f;
|
||||
|
||||
// retrieve date/time from registers
|
||||
int const year = bcd_to_integer(m_reg[7]);
|
||||
int const month = bcd_to_integer(m_reg[6]);
|
||||
int const day = bcd_to_integer(m_reg[5]);
|
||||
int const day_of_week = bcd_to_integer(m_reg[4] & 0x7);
|
||||
int hour = bcd_to_integer(m_reg[3] & 0x3f);
|
||||
int const minute = bcd_to_integer(m_reg[2]);
|
||||
int const second = bcd_to_integer(m_reg[1]);
|
||||
|
||||
// check for 12 hour mode
|
||||
if (m_reg[3] & REG3_12)
|
||||
{
|
||||
hour = bcd_to_integer(m_reg[3] & 0x1f);
|
||||
|
||||
// adjust for PM
|
||||
if (m_reg[3] & REG3_PM)
|
||||
hour = (hour + 12) % 24;
|
||||
}
|
||||
|
||||
// update clock
|
||||
LOG("time/date set %d-%d-%d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
|
||||
set_time(false, year, month, day, day_of_week, hour, minute, second);
|
||||
|
||||
m_mode = MODE_IDLE;
|
||||
m_count = 0;
|
||||
|
||||
update_ceo();
|
||||
}
|
||||
else
|
||||
m_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ds1215_device_base::timer(s32 param)
|
||||
{
|
||||
// register 4 bit 5 disables oscillator
|
||||
if (m_reg[4] & REG4_OSC)
|
||||
return;
|
||||
|
||||
int const hundredths = bcd_to_integer(m_reg[0]);
|
||||
if (hundredths < 99)
|
||||
m_reg[0] = convert_to_bcd(hundredths + 1);
|
||||
else
|
||||
advance_seconds();
|
||||
}
|
||||
|
||||
void ds1215_device_base::update_ceo()
|
||||
{
|
||||
// ceo is asserted except when in data i/o mode
|
||||
bool const ceo = m_mode != MODE_DATA;
|
||||
|
||||
if (m_ceo_state != ceo)
|
||||
{
|
||||
m_ceo_state = ceo;
|
||||
|
||||
m_ceo(!m_ceo_state);
|
||||
}
|
||||
}
|
||||
|
||||
u8 ds1215_device::read()
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
return read_bit();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ds1215_device::write(u8 data)
|
||||
{
|
||||
write_bit(data & 1);
|
||||
}
|
||||
|
||||
u8 ds1216e_device::read(offs_t offset)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (BIT(offset, 2))
|
||||
return read_bit();
|
||||
else
|
||||
write_bit(BIT(offset, 0));
|
||||
|
||||
return BIT(offset, 0);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
77
src/devices/machine/ds1215.h
Normal file
77
src/devices/machine/ds1215.h
Normal file
@ -0,0 +1,77 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
#ifndef MAME_MACHINE_DS1215_H
|
||||
#define MAME_MACHINE_DS1215_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dirtc.h"
|
||||
|
||||
class ds1215_device_base
|
||||
: public device_t
|
||||
, public device_nvram_interface
|
||||
, public device_rtc_interface
|
||||
{
|
||||
public:
|
||||
auto ceo() { return m_ceo.bind(); }
|
||||
|
||||
bool ceo_r() { return !m_ceo_state; }
|
||||
|
||||
protected:
|
||||
ds1215_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
|
||||
|
||||
// device_t implementation
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
|
||||
// device_nvram_interface implementation
|
||||
virtual bool nvram_read(util::read_stream &file) override;
|
||||
virtual bool nvram_write(util::write_stream &file) override;
|
||||
virtual void nvram_default() override;
|
||||
|
||||
// device_rtc_interface implementation
|
||||
virtual bool rtc_feature_y2k() const override { return false; }
|
||||
virtual bool rtc_feature_leap_year() const override { return true; }
|
||||
virtual void rtc_clock_updated(int year, int month, int day, int day_of_week, int hour, int minute, int second) override;
|
||||
|
||||
u8 read_bit();
|
||||
void write_bit(u8 data);
|
||||
|
||||
private:
|
||||
void timer(s32 param);
|
||||
void update_ceo();
|
||||
|
||||
devcb_write_line m_ceo;
|
||||
emu_timer *m_timer;
|
||||
|
||||
// internal state
|
||||
u8 m_mode;
|
||||
u8 m_count;
|
||||
u8 m_reg[8];
|
||||
bool m_ceo_state;
|
||||
};
|
||||
|
||||
class ds1215_device : public ds1215_device_base
|
||||
{
|
||||
public:
|
||||
ds1215_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 32'768);
|
||||
~ds1215_device() {}
|
||||
|
||||
u8 read();
|
||||
void write(u8 data);
|
||||
};
|
||||
|
||||
class ds1216e_device : public ds1215_device_base
|
||||
{
|
||||
public:
|
||||
ds1216e_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 32'768);
|
||||
~ds1216e_device() {}
|
||||
|
||||
u8 read(offs_t offset);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(DS1215, ds1215_device)
|
||||
DECLARE_DEVICE_TYPE(DS1216E, ds1216e_device)
|
||||
|
||||
#endif // MAME_MACHINE_DS1215_H
|
@ -1,305 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Tim Lindner, R. Belmont
|
||||
/*****************************************************************************************
|
||||
|
||||
ds1315.cpp
|
||||
|
||||
Dallas Semiconductor's Phantom Time Chip DS1315.
|
||||
NOTE: writes are decoded, but the host's time will always be returned when asked.
|
||||
|
||||
November 2017: R. Belmont added capability to emulate DS1216 and other DS121x
|
||||
parts where the clock sits in the same place as a ROM. The backing callback
|
||||
returns the ROM contents when the RTC is locked.
|
||||
|
||||
April 2015: chip enable / chip reset / phantom writes by Karl-Ludwig Deisenhofer
|
||||
|
||||
November 2001: implementation by Tim Lindner
|
||||
|
||||
HOW DOES IT WORK?
|
||||
|
||||
READS: pattern recognition (64 bits in correct order). When RTC finally enables
|
||||
64 bits of data can be read. Chance of accidential pattern recognition is minimal.
|
||||
|
||||
WRITES: two different locations (bits 0 and 1) are used to transfer data to the
|
||||
DS1315. 64 bit with time/date info are transmitted directly after recognition
|
||||
of the magic 64 bit pattern (see read above).
|
||||
**************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ds1315.h"
|
||||
#include "coreutil.h"
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(DS1315, ds1315_device, "ds1315", "Dallas DS1315 Phantom Time Chip")
|
||||
|
||||
ds1315_device::ds1315_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, DS1315, tag, owner, clock),
|
||||
m_backing_read(*this, 0xff),
|
||||
m_mode(),
|
||||
m_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void ds1315_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_count));
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_raw_data));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void ds1315_device::device_reset()
|
||||
{
|
||||
chip_reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
LOCAL VARIABLES
|
||||
***************************************************************************/
|
||||
|
||||
static const uint8_t ds1315_pattern[] =
|
||||
{
|
||||
1, 0, 1, 0, 0, 0, 1, 1,
|
||||
0, 1, 0, 1, 1, 1, 0, 0,
|
||||
1, 1, 0, 0, 0, 1, 0, 1,
|
||||
0, 0, 1, 1, 1, 0, 1, 0,
|
||||
1, 0, 1, 0, 0, 0, 1, 1,
|
||||
0, 1, 0, 1, 1, 1, 0, 0,
|
||||
1, 1, 0, 0, 0, 1, 0, 1,
|
||||
0, 0, 1, 1, 1, 0, 1, 0
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
// automated read, does all the work the real Dallas chip does
|
||||
uint8_t ds1315_device::read(offs_t offset)
|
||||
{
|
||||
if (m_mode == DS_SEEK_MATCHING)
|
||||
{
|
||||
if (offset & 1)
|
||||
{
|
||||
read_1();
|
||||
}
|
||||
else
|
||||
{
|
||||
read_0();
|
||||
}
|
||||
|
||||
if (offset & 4)
|
||||
{
|
||||
m_count = 0;
|
||||
m_mode = DS_SEEK_MATCHING;
|
||||
}
|
||||
|
||||
return m_backing_read(offset);
|
||||
}
|
||||
else if (m_mode == DS_CALENDAR_IO)
|
||||
{
|
||||
return read_data();
|
||||
}
|
||||
|
||||
return 0xff; // shouldn't happen, but compilers don't know that
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_0 (actual data)
|
||||
-------------------------------------------------*/
|
||||
|
||||
uint8_t ds1315_device::read_0()
|
||||
{
|
||||
if (ds1315_pattern[m_count++] == 0)
|
||||
{
|
||||
if (m_count == 64)
|
||||
{
|
||||
/* entire pattern matched */
|
||||
m_count = 0;
|
||||
m_mode = DS_CALENDAR_IO;
|
||||
fill_raw_data();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_count = 0;
|
||||
m_mode = DS_SEEK_MATCHING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_1 (actual data)
|
||||
-------------------------------------------------*/
|
||||
|
||||
uint8_t ds1315_device::read_1()
|
||||
{
|
||||
if (ds1315_pattern[m_count++] == 1)
|
||||
{
|
||||
m_count %= 64;
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_count = 0;
|
||||
m_mode = DS_SEEK_MATCHING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_data
|
||||
-------------------------------------------------*/
|
||||
|
||||
uint8_t ds1315_device::read_data()
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
if (m_mode == DS_CALENDAR_IO)
|
||||
{
|
||||
result = m_raw_data[m_count++];
|
||||
|
||||
if (m_count == 64)
|
||||
{
|
||||
m_mode = DS_SEEK_MATCHING;
|
||||
m_count = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
m_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
fill_raw_data
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ds1315_device::fill_raw_data()
|
||||
{
|
||||
/* This routine calls a standard 'C' library routine to get the current
|
||||
date and time and then fill in the raw data struct.
|
||||
*/
|
||||
|
||||
system_time systime;
|
||||
int raw[8], i, j;
|
||||
|
||||
/* get the current date/time from the core */
|
||||
machine().current_datetime(systime);
|
||||
|
||||
raw[0] = 0; /* tenths and hundreths of seconds are always zero */
|
||||
raw[1] = dec_2_bcd(systime.local_time.second);
|
||||
raw[2] = dec_2_bcd(systime.local_time.minute);
|
||||
raw[3] = dec_2_bcd(systime.local_time.hour);
|
||||
|
||||
raw[4] = dec_2_bcd((systime.local_time.weekday != 0) ? systime.local_time.weekday : 7);
|
||||
raw[5] = dec_2_bcd(systime.local_time.mday);
|
||||
raw[6] = dec_2_bcd(systime.local_time.month + 1);
|
||||
raw[7] = dec_2_bcd(systime.local_time.year - 1900); /* Epoch is 1900 */
|
||||
|
||||
/* Ok now we have the raw bcd bytes. Now we need to push them into our bit array */
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
j = i / 8;
|
||||
m_raw_data[i] = (raw[j] & 0x0001);
|
||||
raw[j] = raw[j] >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
write_data
|
||||
-------------------------------------------------*/
|
||||
|
||||
uint8_t ds1315_device::write_data(offs_t offset)
|
||||
{
|
||||
static int write_count;
|
||||
if (write_count >= 64)
|
||||
write_count = 0;
|
||||
|
||||
if (m_mode == DS_CALENDAR_IO)
|
||||
{
|
||||
m_raw_data[write_count++] = offset & 0x01;
|
||||
|
||||
if (write_count == 64)
|
||||
{
|
||||
write_count = 0;
|
||||
|
||||
m_mode = DS_SEEK_MATCHING;
|
||||
m_count = 0;
|
||||
input_raw_data();
|
||||
}
|
||||
}
|
||||
return 0; // ignore
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
ds1315_input_raw_data
|
||||
|
||||
Routine is called when new date and time has
|
||||
been written to the clock chip. Currently we
|
||||
ignore setting the date and time in the clock
|
||||
chip.
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ds1315_device::input_raw_data()
|
||||
{
|
||||
int raw[8], i, j;
|
||||
raw[0] = raw[1] = raw[2] = raw[3] = raw[4] = raw[5] = raw[6] = raw[7] = 0;
|
||||
uint8_t flag = 1;
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
j = i / 8;
|
||||
if ((i % 8) == 0)
|
||||
flag = 1;
|
||||
|
||||
if (m_raw_data[i] & 1)
|
||||
raw[j] |= flag;
|
||||
flag <<= 1;
|
||||
}
|
||||
raw[0] = bcd_2_dec(raw[0]); // hundreds of seconds
|
||||
raw[1] = bcd_2_dec(raw[1]); // seconds (often set to zero)
|
||||
raw[2] = bcd_2_dec(raw[2]); // minute
|
||||
raw[3] = bcd_2_dec(raw[3]); // hour
|
||||
|
||||
raw[4] = bcd_2_dec(raw[4]); // weekday (10 for Friday ?!)
|
||||
raw[5] = bcd_2_dec(raw[5]); // mday
|
||||
raw[6] = bcd_2_dec(raw[6]); // month
|
||||
raw[7] = bcd_2_dec(raw[7]); // year (two digits)
|
||||
|
||||
logerror("\nDS1315 RTC INPUT (WILL BE IGNORED) mm/dd/yy hh:mm:ss - %02d/%02d/%02d %02d/%02d/%02d",
|
||||
raw[6], raw[5], raw[7], raw[3], raw[2], raw[1]
|
||||
);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
query and reset chip status
|
||||
-------------------------------------------------*/
|
||||
bool ds1315_device::chip_enable()
|
||||
{
|
||||
return (m_mode == DS_CALENDAR_IO);
|
||||
}
|
||||
|
||||
// Set a defined state (important for pattern detection)
|
||||
void ds1315_device::chip_reset()
|
||||
{
|
||||
memset(m_raw_data, 0, sizeof(m_raw_data));
|
||||
m_count = 0;
|
||||
m_mode = DS_SEEK_MATCHING;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Tim Lindner
|
||||
/*********************************************************************
|
||||
|
||||
ds1315.h
|
||||
|
||||
Dallas Semiconductor's Phantom Time Chip DS1315.
|
||||
|
||||
by tim lindner, November 2001.
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_DS1315_H
|
||||
#define MAME_MACHINE_DS1315_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class ds1315_device : public device_t
|
||||
{
|
||||
public:
|
||||
ds1315_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
~ds1315_device() {}
|
||||
|
||||
auto read_backing() { return m_backing_read.bind(); }
|
||||
|
||||
// this handler automates the bits 0/2 stuff
|
||||
uint8_t read(offs_t offset);
|
||||
|
||||
uint8_t read_0();
|
||||
uint8_t read_1();
|
||||
uint8_t read_data();
|
||||
uint8_t write_data(offs_t offset);
|
||||
|
||||
bool chip_enable();
|
||||
void chip_reset();
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override ATTR_COLD;
|
||||
virtual void device_reset() override ATTR_COLD;
|
||||
|
||||
private:
|
||||
devcb_read8 m_backing_read;
|
||||
|
||||
enum mode_t : u8
|
||||
{
|
||||
DS_SEEK_MATCHING,
|
||||
DS_CALENDAR_IO
|
||||
};
|
||||
|
||||
// internal state
|
||||
mode_t m_mode;
|
||||
|
||||
void fill_raw_data();
|
||||
void input_raw_data();
|
||||
|
||||
int m_count;
|
||||
uint8_t m_raw_data[8*8];
|
||||
};
|
||||
|
||||
ALLOW_SAVE_TYPE(ds1315_device::mode_t);
|
||||
|
||||
DECLARE_DEVICE_TYPE(DS1315, ds1315_device)
|
||||
|
||||
#endif // MAME_MACHINE_DS1315_H
|
@ -133,7 +133,7 @@ MIG RAM page 2 $CE02 is the speaker/slot bitfield and $CE03 is the paddle/accele
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/applefdintf.h"
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/ds1215.h"
|
||||
#include "machine/iwm.h"
|
||||
#include "machine/kb3600.h"
|
||||
#include "machine/mos6551.h"
|
||||
@ -294,7 +294,7 @@ public:
|
||||
optional_device<mos6551_device> m_acia1, m_acia2;
|
||||
optional_device<applefdintf_device> m_iwm;
|
||||
optional_device_array<floppy_connector, 4> m_floppy;
|
||||
required_device<ds1315_device> m_ds1315;
|
||||
required_device<ds1216e_device> m_ds1315;
|
||||
optional_device<centronics_device> m_printer_conn;
|
||||
optional_device<output_latch_device> m_printer_out;
|
||||
|
||||
@ -387,7 +387,6 @@ public:
|
||||
void ay3600_ako_w(int state);
|
||||
u8 memexp_r(offs_t offset);
|
||||
void memexp_w(offs_t offset, u8 data);
|
||||
u8 nsc_backing_r(offs_t offset);
|
||||
u8 ace500_c0bx_r(offs_t offset);
|
||||
void ace500_c0bx_w(offs_t offset, u8 data);
|
||||
|
||||
@ -3070,10 +3069,14 @@ u8 apple2e_state::read_int_rom(int slotbias, int offset)
|
||||
return m_rom_ptr[slotbias + offset];
|
||||
}
|
||||
|
||||
return m_ds1315->read(slotbias + offset);
|
||||
}
|
||||
// return data from SmartWatch if /CEO is negated
|
||||
if (m_ds1315->ceo_r())
|
||||
return m_ds1315->read(slotbias + offset);
|
||||
else
|
||||
m_ds1315->read(slotbias + offset);
|
||||
|
||||
u8 apple2e_state::nsc_backing_r(offs_t offset) { return m_rom_ptr[offset]; }
|
||||
return m_rom_ptr[slotbias + offset];
|
||||
}
|
||||
|
||||
u8 apple2e_state::c100_r(offs_t offset) { accel_slot(1 + ((offset >> 8) & 0x7)); return read_slot_rom(1, offset); }
|
||||
u8 apple2e_state::c100_int_r(offs_t offset) { accel_slot(1 + ((offset >> 8) & 0x7)); return read_int_rom(0x100, offset); }
|
||||
@ -5117,7 +5120,7 @@ void apple2e_state::apple2e_common(machine_config &config, bool enhanced, bool r
|
||||
SPEAKER_SOUND(config, A2_SPEAKER_TAG).add_route(ALL_OUTPUTS, "mono", 0.4);
|
||||
|
||||
/* DS1315 for no-slot clock */
|
||||
DS1315(config, m_ds1315, 0).read_backing().set(FUNC(apple2e_state::nsc_backing_r));
|
||||
DS1216E(config, m_ds1315);
|
||||
|
||||
/* RAM */
|
||||
RAM(config, m_ram).set_default_size("64K").set_default_value(0x00);
|
||||
|
@ -350,7 +350,7 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
|
||||
#include "machine/timer.h"
|
||||
#include "machine/ram.h"
|
||||
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/ds1215.h"
|
||||
#include "emupal.h"
|
||||
#include "softlist.h"
|
||||
#include "screen.h"
|
||||
@ -492,7 +492,6 @@ public:
|
||||
m_p_vol_ram(*this, "vol_ram"),
|
||||
m_p_nvram(*this, "nvram"),
|
||||
|
||||
m_rtc(*this, "rtc"),
|
||||
m_hgdc(*this, "upd7220"), // GDC
|
||||
|
||||
m_screen2(*this, "screen2"),
|
||||
@ -519,8 +518,6 @@ protected:
|
||||
|
||||
uint8_t ext_ram_r(offs_t offset);
|
||||
|
||||
void rtc_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t read_video_ram_r(offs_t offset);
|
||||
void video_interrupt(int state);
|
||||
|
||||
@ -650,8 +647,6 @@ protected:
|
||||
required_shared_ptr<uint8_t> m_p_vol_ram;
|
||||
required_shared_ptr<uint8_t> m_p_nvram;
|
||||
|
||||
optional_device<ds1315_device> m_rtc;
|
||||
|
||||
required_device<upd7220_device> m_hgdc; // GDC
|
||||
required_device<screen_device> m_screen2;
|
||||
required_device<palette_device> m_palette2;
|
||||
@ -753,7 +748,8 @@ class rainbow_modela_state : public rainbow_base_state
|
||||
{
|
||||
public:
|
||||
rainbow_modela_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
rainbow_base_state(mconfig, type, tag)
|
||||
rainbow_base_state(mconfig, type, tag),
|
||||
m_rtc(*this, "rtc")
|
||||
{
|
||||
}
|
||||
|
||||
@ -767,15 +763,19 @@ private:
|
||||
|
||||
void ext_ram_w(offs_t offset, uint8_t data);
|
||||
uint8_t rtc_r(offs_t offset);
|
||||
void rtc_w(offs_t offset, uint8_t data);
|
||||
void irq_hi_w(int state);
|
||||
uint8_t system_parameter_r();
|
||||
|
||||
required_device<ds1215_device> m_rtc;
|
||||
};
|
||||
|
||||
class rainbow_modelb_state : public rainbow_base_state
|
||||
{
|
||||
public:
|
||||
rainbow_modelb_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
rainbow_base_state(mconfig, type, tag)
|
||||
rainbow_base_state(mconfig, type, tag),
|
||||
m_rtc(*this, "rtc")
|
||||
{
|
||||
}
|
||||
|
||||
@ -791,6 +791,8 @@ private:
|
||||
uint8_t rtc_r(offs_t offset);
|
||||
void irq_hi_w(int state);
|
||||
uint8_t system_parameter_r();
|
||||
|
||||
required_device<ds1216e_device> m_rtc;
|
||||
};
|
||||
|
||||
// It * should be * OK to RESET the SCROLL_BUFFER and the COLOR_MAP (at least with WELL WRITTEN programs)
|
||||
@ -1180,8 +1182,6 @@ void rainbow_base_state::machine_reset()
|
||||
|
||||
m_crtc->MHFU(MHFU_RESET_and_DISABLE);
|
||||
|
||||
m_rtc->chip_reset(); // * Reset RTC to a defined state *
|
||||
|
||||
// *********** HARD DISK CONTROLLERS...
|
||||
address_space &io = m_i8088->space(AS_IO);
|
||||
if (m_inp5->read() == 0x01) // ...PRESENT?
|
||||
@ -1528,27 +1528,20 @@ void rainbow_modelb_state::ext_ram_w(offs_t offset, uint8_t data)
|
||||
|
||||
// Requires a short program from the Suitable Solutions ClikClok distribution disk (CLIKA.COM)
|
||||
// - also needed to set time/date (*). Reads $ed000, writes ed0fe/ed0ff.
|
||||
void rainbow_base_state::rtc_w(offs_t offset, uint8_t data)
|
||||
void rainbow_modela_state::rtc_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (m_inp11->read() == 0x01) // if enabled...
|
||||
{
|
||||
switch (offset)
|
||||
if (m_rtc->ceo_r())
|
||||
{
|
||||
case 0x00: // Write to 0xED0FE
|
||||
if (m_rtc->chip_enable())
|
||||
m_rtc->write_data(offset & 0x01); // Transfer data to DS1315 (data = offset):
|
||||
else
|
||||
m_rtc->read_0(); // (RTC ACTIVATION) read magic pattern 0
|
||||
break;
|
||||
m_rtc->write(offset & 0x01);
|
||||
|
||||
case 0x01: // Write to 0xED0FF
|
||||
if (m_rtc->chip_enable())
|
||||
m_rtc->write_data(offset & 0x01); // Transfer data to DS1315 (data = offset):
|
||||
else
|
||||
m_rtc->read_1(); // (RTC ACTIVATION) read magic pattern 1
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
m_rtc->write(offset & 0x01);
|
||||
}
|
||||
|
||||
m_p_vol_ram[offset] = data; // Poke value into VOL_RAM.
|
||||
}
|
||||
|
||||
@ -1561,10 +1554,10 @@ uint8_t rainbow_modela_state::rtc_r(offs_t offset)
|
||||
{
|
||||
if (offset == 0x00) // read time/date from 0xED000 (ClikClok for 100-A)
|
||||
{
|
||||
if (m_rtc->chip_enable())
|
||||
return m_rtc->read_data() & 0x01;
|
||||
if (m_rtc->ceo_r())
|
||||
return m_rtc->read();
|
||||
else
|
||||
m_rtc->chip_reset();
|
||||
m_rtc->read();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1575,41 +1568,10 @@ uint8_t rainbow_modelb_state::rtc_r(offs_t offset)
|
||||
{
|
||||
if (m_inp11->read() == 0x01) // if enabled...
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
// Transfer data to DS1315 (data = offset):
|
||||
case 0x0000: // RTC_WRITE_DATA_0 0xFC000
|
||||
case 0x2000: // RTC_WRITE_DATA_0 0xFE000 (MIRROR)
|
||||
|
||||
case 0x0001: // RTC_WRITE_DATA_1 0xFC001
|
||||
case 0x2001: // RTC_WRITE_DATA_1 0xFE001 (MIRROR)
|
||||
m_rtc->write_data(offset & 0x01);
|
||||
break;
|
||||
|
||||
// Read actual time/date from ClikClok:
|
||||
case 0x0004: // 0xFC004
|
||||
case 0x2004: // 0xFE004 (MIRROR)
|
||||
if (m_rtc->chip_enable())
|
||||
return (m_rtc->read_data() & 0x01);
|
||||
[[fallthrough]]; // FIXME: really?
|
||||
// (RTC ACTIVATION) read magic pattern 0
|
||||
case 0x0100: // 0xFC100
|
||||
case 0x2100: // 0xFE100 (MIRROR)
|
||||
m_rtc->read_0();
|
||||
break;
|
||||
|
||||
// (RTC ACTIVATION) read magic pattern 1
|
||||
case 0x0101: // 0xFC101
|
||||
case 0x2101: // 0xFE101 (MIRROR)
|
||||
m_rtc->read_1();
|
||||
break;
|
||||
|
||||
// RESET
|
||||
case 0x0104: // 0xFC104
|
||||
case 0x2104: // 0xFE104 (MIRROR)
|
||||
m_rtc->chip_reset();
|
||||
break;
|
||||
}
|
||||
if (m_rtc->ceo_r())
|
||||
return m_rtc->read(offset);
|
||||
else
|
||||
m_rtc->read(offset);
|
||||
}
|
||||
|
||||
uint8_t *rom = memregion("maincpu")->base();
|
||||
@ -3278,8 +3240,6 @@ void rainbow_base_state::rainbow_base(machine_config &config)
|
||||
HARDDISK(config, "harddisk3", "corvus_hdd");
|
||||
HARDDISK(config, "harddisk4", "corvus_hdd");
|
||||
|
||||
DS1315(config, m_rtc, 0); // DS1315 (ClikClok for DEC-100 B) * OPTIONAL *
|
||||
|
||||
COM8116_003(config, m_dbrg, 24.0734_MHz_XTAL / 4); // 6.01835 MHz (nominally 6 MHz)
|
||||
m_dbrg->fr_handler().set(FUNC(rainbow_base_state::dbrg_fr_w));
|
||||
m_dbrg->ft_handler().set(FUNC(rainbow_base_state::dbrg_ft_w));
|
||||
@ -3330,6 +3290,8 @@ void rainbow_modela_state::rainbow_modela(machine_config &config)
|
||||
m_i8088->set_addrmap(AS_IO, &rainbow_modela_state::rainbow8088_io);
|
||||
RAM(config, m_ram).set_default_size("64K").set_extra_options("64K,128K,192K,256K,320K,384K,448K,512K,576K,640K,704K,768K");
|
||||
m_kbd8251->dtr_handler().set(FUNC(rainbow_modela_state::irq_hi_w));
|
||||
|
||||
DS1215(config, m_rtc); // DS1315 (ClikClok for DEC-100 B) * OPTIONAL *
|
||||
}
|
||||
|
||||
void rainbow_modelb_state::rainbow_modelb(machine_config &config)
|
||||
@ -3339,6 +3301,8 @@ void rainbow_modelb_state::rainbow_modelb(machine_config &config)
|
||||
m_i8088->set_addrmap(AS_IO, &rainbow_modelb_state::rainbow8088_io);
|
||||
RAM(config, m_ram).set_default_size("128K").set_extra_options("128K,192K,256K,320K,384K,448K,512K,576K,640K,704K,768K,832K,896K");
|
||||
m_kbd8251->dtr_handler().set(FUNC(rainbow_modelb_state::irq_hi_w));
|
||||
|
||||
DS1216E(config, m_rtc); // DS1315 (ClikClok for DEC-100 B) * OPTIONAL *
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
// other devices
|
||||
#include "machine/aic6250.h"
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/ds1215.h"
|
||||
#include "machine/input_merger.h"
|
||||
#include "machine/mc68681.h"
|
||||
#include "machine/ncr5380.h"
|
||||
@ -72,7 +72,7 @@ protected:
|
||||
required_device<ns32381_device> m_fpu;
|
||||
required_device<ns32202_device> m_icu;
|
||||
|
||||
required_device<ds1315_device> m_rtc;
|
||||
required_device<ds1216e_device> m_rtc;
|
||||
|
||||
required_device<ncr5380_device> m_ncr5380;
|
||||
required_device<aic6250_device> m_aic6250;
|
||||
@ -115,16 +115,13 @@ void pc532_state::machine_start()
|
||||
{
|
||||
// install phantom rtc using memory taps
|
||||
// TODO: not tested
|
||||
m_cpu->space(AS_PROGRAM).install_read_tap(0x1000'0000, 0x1000'0003, "rtc_w",
|
||||
m_cpu->space(AS_PROGRAM).install_read_tap(0x1000'0000, 0x1000'0007, "rtc_r",
|
||||
[this](offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
m_rtc->write_data(offset & 1);
|
||||
});
|
||||
m_cpu->space(AS_PROGRAM).install_read_tap(0x1000'0004, 0x1000'0007, "rtc_r",
|
||||
[this](offs_t offset, u32 &data, u32 mem_mask)
|
||||
{
|
||||
if (m_rtc->chip_enable())
|
||||
data = m_rtc->read_data();
|
||||
if (m_rtc->ceo_r())
|
||||
data = m_rtc->read(offset);
|
||||
else
|
||||
m_rtc->read(offset);
|
||||
});
|
||||
}
|
||||
|
||||
@ -312,7 +309,7 @@ void pc532_state::pc532(machine_config &config)
|
||||
m_icu->out_g<0>().set([this](int state) { m_swap.select(state); });
|
||||
m_icu->out_g<7>().set([this](int state) { m_select.select(state); });
|
||||
|
||||
DS1315(config, m_rtc, 32.768_kHz_XTAL);
|
||||
DS1216E(config, m_rtc);
|
||||
|
||||
NSCSI_BUS(config, "slot");
|
||||
NSCSI_CONNECTOR(config, "slot:0", scsi_devices, "harddisk", false);
|
||||
|
@ -168,7 +168,7 @@ void sgi_ip4_device::device_add_mconfig(machine_config &config)
|
||||
m_cpu->set_addrmap(AS_PROGRAM, &sgi_ip4_device::map);
|
||||
m_cpu->in_brcond<0>().set([]() { return 1; }); // writeback complete
|
||||
|
||||
DS1315(config, m_rtc, 0); // DS1216?
|
||||
DS1215(config, m_rtc); // DS1216B?
|
||||
|
||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // CXK5816PN-15L
|
||||
|
||||
@ -511,10 +511,11 @@ u8 sgi_ip4_device::nvram_r(offs_t offset)
|
||||
{
|
||||
if (offset == 0x7ff && !machine().side_effects_disabled())
|
||||
{
|
||||
if (m_rtc->chip_enable())
|
||||
m_rtc->read_data();
|
||||
// return SmartWatch data if /CEO is negated
|
||||
if (m_rtc->ceo_r())
|
||||
return m_rtc->read();
|
||||
else
|
||||
return m_rtc->read_data();
|
||||
m_rtc->read();
|
||||
}
|
||||
|
||||
return m_nvram[offset];
|
||||
@ -522,21 +523,12 @@ u8 sgi_ip4_device::nvram_r(offs_t offset)
|
||||
|
||||
void sgi_ip4_device::nvram_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (offset != 0x7ff || !m_rtc->chip_enable())
|
||||
// write to NVRAM if SmartWatch /CEO is asserted
|
||||
if (offset != 0x7ff || !m_rtc->ceo_r())
|
||||
m_nvram[offset] = data;
|
||||
|
||||
if (offset == 0x7ff)
|
||||
{
|
||||
if (!m_rtc->chip_enable())
|
||||
{
|
||||
if (data)
|
||||
m_rtc->read_1();
|
||||
else
|
||||
m_rtc->read_0();
|
||||
}
|
||||
else
|
||||
m_rtc->write_data(data);
|
||||
}
|
||||
m_rtc->write(data);
|
||||
}
|
||||
|
||||
ROM_START(ip4)
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "cpu/mips/mips1.h"
|
||||
|
||||
#include "machine/ds1315.h"
|
||||
#include "machine/ds1215.h"
|
||||
#include "machine/mc68681.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/wd33c9x.h"
|
||||
@ -52,7 +52,7 @@ protected:
|
||||
|
||||
private:
|
||||
required_device<mips1_device_base> m_cpu;
|
||||
required_device<ds1315_device> m_rtc;
|
||||
required_device<ds1215_device> m_rtc;
|
||||
required_device<pit8254_device> m_pit;
|
||||
required_device<wd33c9x_base_device> m_scsi;
|
||||
required_device_array<scn2681_device, 3> m_duart;
|
||||
|
Loading…
Reference in New Issue
Block a user