mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Add device emulation for DS17x85 series of MC146818-compatible RTCs with additional features
This commit is contained in:
parent
e9b55b8155
commit
83e63dacf4
@ -992,6 +992,18 @@ if (MACHINES["DS1386"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/ds17x85.h,MACHINES["DS17X85"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["DS17X85"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/ds17x85.cpp",
|
||||
MAME_DIR .. "src/devices/machine/ds17x85.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/ds1994.h,MACHINES["DS1994"] = true
|
||||
|
@ -447,6 +447,7 @@ MACHINES["DS1205"] = true
|
||||
MACHINES["DS1302"] = true
|
||||
--MACHINES["DS1315"] = true
|
||||
--MACHINES["DS1386"] = true
|
||||
MACHINES["DS17X85"] = true
|
||||
MACHINES["DS1994"] = true
|
||||
MACHINES["DS2401"] = true
|
||||
MACHINES["DS2404"] = true
|
||||
|
@ -454,6 +454,7 @@ MACHINES["DP8573"] = true
|
||||
MACHINES["DS1302"] = true
|
||||
MACHINES["DS1315"] = true
|
||||
MACHINES["DS1386"] = true
|
||||
MACHINES["DS17X85"] = true
|
||||
MACHINES["DS2401"] = true
|
||||
MACHINES["DS2404"] = true
|
||||
MACHINES["DS75160A"] = true
|
||||
|
@ -19,7 +19,7 @@ ds12885_device::ds12885_device(const machine_config &mconfig, device_type type,
|
||||
{
|
||||
}
|
||||
|
||||
int ds12885_device::get_timer_bypass()
|
||||
int ds12885_device::get_timer_bypass() const
|
||||
{
|
||||
if( !( m_data[REG_A] & REG_A_DV0 ) ) //DV0 must be 0 for timekeeping
|
||||
{
|
||||
|
@ -17,8 +17,8 @@ public:
|
||||
protected:
|
||||
ds12885_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
virtual int data_size() override { return 128; }
|
||||
virtual int get_timer_bypass() override;
|
||||
virtual int data_size() const override { return 128; }
|
||||
virtual int get_timer_bypass() const override;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
@ -37,7 +37,7 @@ public:
|
||||
void write_extended(offs_t offset, uint8_t data);
|
||||
|
||||
protected:
|
||||
virtual int data_size() override { return 256; }
|
||||
virtual int data_size() const override { return 256; }
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
286
src/devices/machine/ds17x85.cpp
Normal file
286
src/devices/machine/ds17x85.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Dallas DS17x85/DS17x87 Real Time Clocks with extended NVSRAM
|
||||
|
||||
These MC146818-compatible RTCs overlay the last 64 bytes of user
|
||||
RAM (not provided by the MC146818) with a second page of registers,
|
||||
including a Y2K-updated century count and registers for indirectly
|
||||
accessing extended SRAM which is backed with a separate auxiliary
|
||||
battery power input.
|
||||
|
||||
The DS1685 and DS17x85 use conventional PDIP/SO/TSOP packages,
|
||||
while the DS1687 and DS17x87 integrate battery, oscillator and chip
|
||||
into one of Dallas's trademark EDIPs. They are indistinguishable
|
||||
from the perspective of software.
|
||||
|
||||
Currently unemulated features include:
|
||||
- Kickstart input
|
||||
- Date alarm wakeup
|
||||
- Increment in progress flag
|
||||
- RAM clear function (software-enabled, hardware-triggered)
|
||||
- 32.768 kHz frequency option for SQW output
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ds17x85.h"
|
||||
|
||||
#define VERBOSE 0
|
||||
#include "logmacro.h"
|
||||
|
||||
// device type definitions
|
||||
DEFINE_DEVICE_TYPE(DS1685, ds1685_device, "ds1685", "DS1685 RTC")
|
||||
DEFINE_DEVICE_TYPE(DS1687, ds1687_device, "ds1687", "DS1687 RTC")
|
||||
DEFINE_DEVICE_TYPE(DS17285, ds17285_device, "ds17285", "DS17285 RTC")
|
||||
DEFINE_DEVICE_TYPE(DS17287, ds17287_device, "ds17287", "DS17287 RTC")
|
||||
DEFINE_DEVICE_TYPE(DS17485, ds17485_device, "ds17485", "DS17485 RTC")
|
||||
DEFINE_DEVICE_TYPE(DS17487, ds17487_device, "ds17487", "DS17487 RTC")
|
||||
DEFINE_DEVICE_TYPE(DS17885, ds17885_device, "ds17885", "DS17885 RTC")
|
||||
DEFINE_DEVICE_TYPE(DS17887, ds17887_device, "ds17887", "DS17887 RTC")
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds17x85_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds17x85_device::ds17x85_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 model, u32 extram_size)
|
||||
: mc146818_device(mconfig, type, tag, owner, clock)
|
||||
, m_model(model)
|
||||
, m_extram_size(extram_size)
|
||||
, m_smi_stack1(0)
|
||||
{
|
||||
m_century_index = REG_EXT_CENTURY;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds1685_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds1685_device::ds1685_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS1685, tag, owner, clock, 0x71, 128)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds1687_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds1687_device::ds1687_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS1687, tag, owner, clock, 0x71, 128)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds17285_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds17285_device::ds17285_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS17285, tag, owner, clock, 0x72, 2048)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds17287_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds17287_device::ds17287_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS17287, tag, owner, clock, 0x72, 2048)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds17485_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds17485_device::ds17485_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS17485, tag, owner, clock, 0x74, 4096)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds17487_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds17487_device::ds17487_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS17487, tag, owner, clock, 0x74, 4096)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds17885_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds17885_device::ds17885_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS17885, tag, owner, clock, 0x78, 8192)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// ds17887_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ds17887_device::ds17887_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: ds17x85_device(mconfig, DS17887, tag, owner, clock, 0x78, 8192)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void ds17x85_device::device_start()
|
||||
{
|
||||
mc146818_device::device_start();
|
||||
|
||||
save_item(NAME(m_smi_stack1));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_default - called to initialize NVRAM to
|
||||
// its default state
|
||||
//-------------------------------------------------
|
||||
|
||||
void ds17x85_device::nvram_default()
|
||||
{
|
||||
mc146818_device::nvram_default();
|
||||
|
||||
if (!m_region.found())
|
||||
{
|
||||
// initialize read-only model number and 64-bit serial number
|
||||
m_data[REG_EXT_MODEL] = m_model;
|
||||
m_data[REG_EXT_SERIAL1] = 0x4d;
|
||||
m_data[REG_EXT_SERIAL2] = 0x41;
|
||||
m_data[REG_EXT_SERIAL3] = 0x4d;
|
||||
m_data[REG_EXT_SERIAL4] = 0x45;
|
||||
m_data[REG_EXT_SERIAL5] = 0x64;
|
||||
m_data[REG_EXT_SERIAL6] = 0x76;
|
||||
m_data[REG_EXT_SERIAL_CRC] = 0xf8;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// get_timer_bypass - get main clock divisor based on A register
|
||||
//---------------------------------------------------------------
|
||||
|
||||
int ds17x85_device::get_timer_bypass() const
|
||||
{
|
||||
int bypass;
|
||||
|
||||
// DV0 is used for bank switching only
|
||||
switch (m_data[REG_A] & (REG_A_DV2 | REG_A_DV1))
|
||||
{
|
||||
case REG_A_DV1:
|
||||
bypass = 7;
|
||||
break;
|
||||
|
||||
case REG_A_DV2 | REG_A_DV1:
|
||||
bypass = 22;
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO: other combinations of divider bits disable the oscillator
|
||||
bypass = 22;
|
||||
break;
|
||||
}
|
||||
|
||||
return bypass;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// internal_set_address - latch address on ALE
|
||||
//---------------------------------------------------------------
|
||||
|
||||
void ds17x85_device::internal_set_address(uint8_t address)
|
||||
{
|
||||
// push previous address onto SMI recovery stack
|
||||
m_data[REG_EXT_SMI_STACK3] = m_data[REG_EXT_SMI_STACK2];
|
||||
m_data[REG_EXT_SMI_STACK2] = m_smi_stack1;
|
||||
m_smi_stack1 = m_index | ((m_data[REG_A] & REG_A_DV0) ? 0x80 : 0x00);
|
||||
|
||||
mc146818_device::internal_set_address(address);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// internal_read - read internal data
|
||||
//---------------------------------------------------------------
|
||||
|
||||
uint8_t ds17x85_device::internal_read(offs_t offset)
|
||||
{
|
||||
if (offset >= 0x40 && (m_data[REG_A] & REG_A_DV0))
|
||||
{
|
||||
offset += 0x40;
|
||||
switch (offset)
|
||||
{
|
||||
case REG_EXT_4A:
|
||||
return m_data[offset] | REG_EXT_4A_VRT2;
|
||||
|
||||
case REG_EXT_RAM_DATA:
|
||||
LOG("%s: Reading from extended RAM at %04X\n", machine().describe_context(),
|
||||
m_data[REG_EXT_RAM_ADDRL] | offs_t(m_data[REG_EXT_RAM_ADDRH]) << 8);
|
||||
offset = REG_EXT_RAM_BASE + (m_data[REG_EXT_RAM_ADDRL] | offs_t(m_data[REG_EXT_RAM_ADDRH]) << 8) % m_extram_size;
|
||||
if ((m_data[REG_EXT_4A] & REG_EXT_4A_BME) && !machine().side_effects_disabled())
|
||||
{
|
||||
m_data[REG_EXT_RAM_ADDRL]++;
|
||||
if (m_data[REG_EXT_RAM_ADDRL] == 0 && m_extram_size > 256)
|
||||
m_data[REG_EXT_RAM_ADDRH]++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mc146818_device::internal_read(offset);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
// internal_write - write internal data
|
||||
//---------------------------------------------------------------
|
||||
|
||||
void ds17x85_device::internal_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
m_data[REG_EXT_WRITE_COUNTER]++;
|
||||
|
||||
if (offset >= 0x40 && (m_data[REG_A] & REG_A_DV0))
|
||||
{
|
||||
offset += 0x40;
|
||||
switch (offset)
|
||||
{
|
||||
case REG_EXT_RAM_DATA:
|
||||
LOG("%s: Writing %02X to extended RAM at %04X\n", machine().describe_context(),
|
||||
data, m_data[REG_EXT_RAM_ADDRL] | offs_t(m_data[REG_EXT_RAM_ADDRH]) << 8);
|
||||
offset = REG_EXT_RAM_BASE + (m_data[REG_EXT_RAM_ADDRL] | offs_t(m_data[REG_EXT_RAM_ADDRH]) << 8) % m_extram_size;
|
||||
if ((m_data[REG_EXT_4A] & REG_EXT_4A_BME) && !machine().side_effects_disabled())
|
||||
{
|
||||
m_data[REG_EXT_RAM_ADDRL]++;
|
||||
if (m_data[REG_EXT_RAM_ADDRL] == 0 && m_extram_size > 256)
|
||||
m_data[REG_EXT_RAM_ADDRH]++;
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_EXT_CENTURY:
|
||||
case REG_EXT_DATE_ALARM: // TODO: unimplemented
|
||||
case REG_EXT_4A: // TODO: mostly unimplemented
|
||||
case REG_EXT_4B: // TODO: unimplemented
|
||||
case REG_EXT_RAM_ADDRL:
|
||||
break;
|
||||
|
||||
case REG_EXT_RAM_ADDRH:
|
||||
if (m_extram_size <= 256)
|
||||
{
|
||||
logerror("%s: RTC extended addressing uses one byte only\n", machine().describe_context());
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("%s: Write to reserved/read-only bank 1 register %02X\n", machine().describe_context(), offset - 0x40);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mc146818_device::internal_write(offset, data);
|
||||
}
|
192
src/devices/machine/ds17x85.h
Normal file
192
src/devices/machine/ds17x85.h
Normal file
@ -0,0 +1,192 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Dallas DS17x85/DS17x87 Real Time Clocks with extended NVSRAM
|
||||
|
||||
***********************************************************************
|
||||
_____ _____
|
||||
/PWR 1 |* \_/ | 24 Vcc
|
||||
(DS17x87: N.C.) X1 2 | | 23 SQW
|
||||
(DS17x87: N.C.) X2 3 | | 22 Vbaux
|
||||
AD0 4 | | 21 /RCLR
|
||||
AD1 5 | DS168x | 20 Vbat (DS17x87: N.C.)
|
||||
AD2 6 | DS1728x | 19 /IRQ
|
||||
AD3 7 | DS1748x | 18 /KS
|
||||
AD4 8 | DS1788x | 17 /RD
|
||||
AD5 9 | | 16 GND (DS17x87: N.C.)
|
||||
AD6 10 | | 15 /WR
|
||||
AD7 11 | | 14 ALE
|
||||
GND 12 |_____________| 13 /CS
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_DS17X85_H
|
||||
#define MAME_MACHINE_DS17X85_H 1
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mc146818.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> ds17x85_device
|
||||
|
||||
class ds17x85_device : public mc146818_device
|
||||
{
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
REG_EXT_MODEL = 0x40 + 0x40,
|
||||
REG_EXT_SERIAL1 = 0x40 + 0x41,
|
||||
REG_EXT_SERIAL2 = 0x40 + 0x42,
|
||||
REG_EXT_SERIAL3 = 0x40 + 0x43,
|
||||
REG_EXT_SERIAL4 = 0x40 + 0x44,
|
||||
REG_EXT_SERIAL5 = 0x40 + 0x45,
|
||||
REG_EXT_SERIAL6 = 0x40 + 0x46,
|
||||
REG_EXT_SERIAL_CRC = 0x40 + 0x47,
|
||||
REG_EXT_CENTURY = 0x40 + 0x48,
|
||||
REG_EXT_DATE_ALARM = 0x40 + 0x49,
|
||||
REG_EXT_4A = 0x40 + 0x4a,
|
||||
REG_EXT_4B = 0x40 + 0x4b,
|
||||
REG_EXT_SMI_STACK2 = 0x40 + 0x4e,
|
||||
REG_EXT_SMI_STACK3 = 0x40 + 0x4f,
|
||||
REG_EXT_RAM_ADDRL = 0x40 + 0x50,
|
||||
REG_EXT_RAM_ADDRH = 0x40 + 0x51,
|
||||
REG_EXT_RAM_DATA = 0x40 + 0x53,
|
||||
REG_EXT_WRITE_COUNTER = 0x40 + 0x5e,
|
||||
REG_EXT_RAM_BASE = 0x40 + 0x80
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REG_EXT_4A_VRT2 = 0x80,
|
||||
REG_EXT_4A_INCR = 0x40,
|
||||
REG_EXT_4A_BME = 0x20,
|
||||
REG_EXT_4A_PAB = 0x08,
|
||||
REG_EXT_4A_RF = 0x04,
|
||||
REG_EXT_4A_WF = 0x02,
|
||||
REG_EXT_4A_KF = 0x01
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REG_EXT_4B_ABE = 0x80,
|
||||
REG_EXT_4B_E32k = 0x40,
|
||||
REG_EXT_4B_CS = 0x20,
|
||||
REG_EXT_4B_RCE = 0x10,
|
||||
REG_EXT_4B_PRS = 0x08,
|
||||
REG_EXT_4B_RIE = 0x04,
|
||||
REG_EXT_4B_WIE = 0x02,
|
||||
REG_EXT_4B_KSE = 0x01
|
||||
};
|
||||
|
||||
ds17x85_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 model, u32 extram_size);
|
||||
|
||||
// device-specific overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
// device_nvram_interface overrides
|
||||
virtual void nvram_default() override;
|
||||
|
||||
// mc146818_device overrides
|
||||
virtual int data_size() const override { return REG_EXT_RAM_BASE + m_extram_size; }
|
||||
virtual int data_logical_size() const override { return 128; }
|
||||
virtual bool century_count_enabled() const override { return true; }
|
||||
virtual int get_timer_bypass() const override;
|
||||
virtual void internal_set_address(uint8_t data) override;
|
||||
virtual uint8_t internal_read(offs_t offset) override;
|
||||
virtual void internal_write(offs_t offset, uint8_t data) override;
|
||||
|
||||
private:
|
||||
const u8 m_model;
|
||||
const u32 m_extram_size;
|
||||
|
||||
u8 m_smi_stack1;
|
||||
};
|
||||
|
||||
// ======================> ds1685_device
|
||||
|
||||
class ds1685_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds1685_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// ======================> ds1687_device
|
||||
|
||||
class ds1687_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds1687_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// ======================> ds17285_device
|
||||
|
||||
class ds17285_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds17285_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// ======================> ds17287_device
|
||||
|
||||
class ds17287_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds17287_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// ======================> ds17485_device
|
||||
|
||||
class ds17485_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds17485_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// ======================> ds17487_device
|
||||
|
||||
class ds17487_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds17487_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// ======================> ds17885_device
|
||||
|
||||
class ds17885_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds17885_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// ======================> ds17887_device
|
||||
|
||||
class ds17887_device : public ds17x85_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
ds17887_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
// device type declarations
|
||||
DECLARE_DEVICE_TYPE(DS1685, ds1685_device)
|
||||
DECLARE_DEVICE_TYPE(DS1687, ds1687_device)
|
||||
DECLARE_DEVICE_TYPE(DS17285, ds17285_device)
|
||||
DECLARE_DEVICE_TYPE(DS17287, ds17287_device)
|
||||
DECLARE_DEVICE_TYPE(DS17485, ds17485_device)
|
||||
DECLARE_DEVICE_TYPE(DS17487, ds17487_device)
|
||||
DECLARE_DEVICE_TYPE(DS17885, ds17885_device)
|
||||
DECLARE_DEVICE_TYPE(DS17887, ds17887_device)
|
||||
|
||||
#endif // MAME_MACHINE_DS17X85_H
|
@ -54,12 +54,15 @@ mc146818_device::mc146818_device(const machine_config &mconfig, device_type type
|
||||
|
||||
void mc146818_device::device_start()
|
||||
{
|
||||
m_data.resize(data_size());
|
||||
m_data = make_unique_clear<uint8_t[]>(data_size());
|
||||
m_last_refresh = machine().time();
|
||||
m_clock_timer = timer_alloc(TIMER_CLOCK);
|
||||
m_periodic_timer = timer_alloc(TIMER_PERIODIC);
|
||||
|
||||
m_write_irq.resolve_safe();
|
||||
|
||||
save_pointer(NAME(m_data), data_size());
|
||||
save_item(NAME(m_index));
|
||||
}
|
||||
|
||||
|
||||
@ -147,7 +150,20 @@ void mc146818_device::device_timer(emu_timer &timer, device_timer_id id, int par
|
||||
{
|
||||
set_month(1);
|
||||
|
||||
set_year((get_year() + 1) % 100);
|
||||
int year = get_year() + 1;
|
||||
if (year <= 99)
|
||||
{
|
||||
set_year(year);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_year(0);
|
||||
|
||||
if (century_count_enabled())
|
||||
{
|
||||
set_century((get_century() + 1) % 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,15 +197,14 @@ void mc146818_device::device_timer(emu_timer &timer, device_timer_id id, int par
|
||||
void mc146818_device::nvram_default()
|
||||
{
|
||||
// populate from a memory region if present
|
||||
memory_region *region = memregion(DEVICE_SELF);
|
||||
if (region != nullptr)
|
||||
if (m_region.found())
|
||||
{
|
||||
uint32_t bytes = region->bytes();
|
||||
uint32_t bytes = m_region->bytes();
|
||||
|
||||
if (bytes > data_size())
|
||||
bytes = data_size();
|
||||
|
||||
memcpy(&m_data[0], region->base(), bytes);
|
||||
memcpy(&m_data[0], m_region->base(), bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -237,7 +252,7 @@ void mc146818_device::nvram_write(emu_file &file)
|
||||
// to_ram - convert value to current ram format
|
||||
//-------------------------------------------------
|
||||
|
||||
int mc146818_device::to_ram(int a)
|
||||
int mc146818_device::to_ram(int a) const
|
||||
{
|
||||
if (!(m_data[REG_B] & REG_B_DM))
|
||||
return dec_2_bcd(a);
|
||||
@ -250,7 +265,7 @@ int mc146818_device::to_ram(int a)
|
||||
// from_ram - convert value from current ram format
|
||||
//-------------------------------------------------
|
||||
|
||||
int mc146818_device::from_ram(int a)
|
||||
int mc146818_device::from_ram(int a) const
|
||||
{
|
||||
if (!(m_data[REG_B] & REG_B_DM))
|
||||
return bcd_2_dec(a);
|
||||
@ -259,7 +274,7 @@ int mc146818_device::from_ram(int a)
|
||||
}
|
||||
|
||||
|
||||
int mc146818_device::get_seconds()
|
||||
int mc146818_device::get_seconds() const
|
||||
{
|
||||
return from_ram(m_data[REG_SECONDS]);
|
||||
}
|
||||
@ -269,7 +284,7 @@ void mc146818_device::set_seconds(int seconds)
|
||||
m_data[REG_SECONDS] = to_ram(seconds);
|
||||
}
|
||||
|
||||
int mc146818_device::get_minutes()
|
||||
int mc146818_device::get_minutes() const
|
||||
{
|
||||
return from_ram(m_data[REG_MINUTES]);
|
||||
}
|
||||
@ -279,7 +294,7 @@ void mc146818_device::set_minutes(int minutes)
|
||||
m_data[REG_MINUTES] = to_ram(minutes);
|
||||
}
|
||||
|
||||
int mc146818_device::get_hours()
|
||||
int mc146818_device::get_hours() const
|
||||
{
|
||||
if (!(m_data[REG_B] & REG_B_24_12))
|
||||
{
|
||||
@ -328,7 +343,7 @@ void mc146818_device::set_hours(int hours)
|
||||
}
|
||||
}
|
||||
|
||||
int mc146818_device::get_dayofweek()
|
||||
int mc146818_device::get_dayofweek() const
|
||||
{
|
||||
return from_ram(m_data[REG_DAYOFWEEK]);
|
||||
}
|
||||
@ -338,7 +353,7 @@ void mc146818_device::set_dayofweek(int dayofweek)
|
||||
m_data[REG_DAYOFWEEK] = to_ram(dayofweek);
|
||||
}
|
||||
|
||||
int mc146818_device::get_dayofmonth()
|
||||
int mc146818_device::get_dayofmonth() const
|
||||
{
|
||||
return from_ram(m_data[REG_DAYOFMONTH]);
|
||||
}
|
||||
@ -348,7 +363,7 @@ void mc146818_device::set_dayofmonth(int dayofmonth)
|
||||
m_data[REG_DAYOFMONTH] = to_ram(dayofmonth);
|
||||
}
|
||||
|
||||
int mc146818_device::get_month()
|
||||
int mc146818_device::get_month() const
|
||||
{
|
||||
return from_ram(m_data[REG_MONTH]);
|
||||
}
|
||||
@ -358,7 +373,7 @@ void mc146818_device::set_month(int month)
|
||||
m_data[REG_MONTH] = to_ram(month);
|
||||
}
|
||||
|
||||
int mc146818_device::get_year()
|
||||
int mc146818_device::get_year() const
|
||||
{
|
||||
return from_ram(m_data[REG_YEAR]);
|
||||
}
|
||||
@ -368,6 +383,18 @@ void mc146818_device::set_year(int year)
|
||||
m_data[REG_YEAR] = to_ram(year);
|
||||
}
|
||||
|
||||
int mc146818_device::get_century() const
|
||||
{
|
||||
assert(m_century_index != -1);
|
||||
return from_ram(m_data[m_century_index]);
|
||||
}
|
||||
|
||||
void mc146818_device::set_century(int century)
|
||||
{
|
||||
assert(m_century_index != -1);
|
||||
m_data[m_century_index] = to_ram(century);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -400,7 +427,7 @@ void mc146818_device::set_base_datetime()
|
||||
set_year((current_time.year - m_epoch) % 100);
|
||||
|
||||
if (m_century_index >= 0)
|
||||
m_data[m_century_index] = to_ram(current_time.year / 100);
|
||||
set_century(current_time.year / 100);
|
||||
}
|
||||
|
||||
|
||||
@ -410,9 +437,7 @@ void mc146818_device::set_base_datetime()
|
||||
|
||||
void mc146818_device::update_timer()
|
||||
{
|
||||
int bypass;
|
||||
|
||||
bypass = get_timer_bypass();
|
||||
int bypass = get_timer_bypass();
|
||||
|
||||
attotime update_period = attotime::never;
|
||||
attotime update_interval = attotime::never;
|
||||
@ -452,7 +477,7 @@ void mc146818_device::update_timer()
|
||||
// get_timer_bypass - get main clock divisor based on A register
|
||||
//---------------------------------------------------------------
|
||||
|
||||
int mc146818_device::get_timer_bypass()
|
||||
int mc146818_device::get_timer_bypass() const
|
||||
{
|
||||
int bypass;
|
||||
|
||||
@ -520,7 +545,8 @@ uint8_t mc146818_device::read(offs_t offset)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
data = read_direct(m_index);
|
||||
data = internal_read(m_index);
|
||||
LOG("mc146818_port_r(): offset=0x%02x data=0x%02x\n", m_index, data);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -528,6 +554,54 @@ uint8_t mc146818_device::read(offs_t offset)
|
||||
}
|
||||
|
||||
uint8_t mc146818_device::read_direct(offs_t offset)
|
||||
{
|
||||
offset %= data_logical_size();
|
||||
if (!machine().side_effects_disabled())
|
||||
internal_set_address(offset);
|
||||
|
||||
uint8_t data = internal_read(offset);
|
||||
|
||||
LOG("mc146818_port_r(): offset=0x%02x data=0x%02x\n", offset, data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// write - I/O handler for writing
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::write(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
internal_set_address(data % data_logical_size());
|
||||
break;
|
||||
|
||||
case 1:
|
||||
LOG("mc146818_port_w(): offset=0x%02x data=0x%02x\n", m_index, data);
|
||||
internal_write(m_index, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mc146818_device::write_direct(offs_t offset, uint8_t data)
|
||||
{
|
||||
offset %= data_logical_size();
|
||||
if (!machine().side_effects_disabled())
|
||||
internal_set_address(offset);
|
||||
|
||||
LOG("mc146818_port_w(): offset=0x%02x data=0x%02x\n", offset, data);
|
||||
|
||||
internal_write(offset, data);
|
||||
}
|
||||
|
||||
void mc146818_device::internal_set_address(uint8_t address)
|
||||
{
|
||||
m_index = address;
|
||||
}
|
||||
|
||||
uint8_t mc146818_device::internal_read(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
@ -546,8 +620,11 @@ uint8_t mc146818_device::read_direct(offs_t offset)
|
||||
// the unused bits b0 ... b3 are always read as 0
|
||||
data = m_data[REG_C] & (REG_C_IRQF | REG_C_PF | REG_C_AF | REG_C_UF);
|
||||
// read 0x0c will clear all IRQ flags in register 0x0c
|
||||
m_data[REG_C] &= ~(REG_C_IRQF | REG_C_PF | REG_C_AF | REG_C_UF);
|
||||
update_irq();
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
m_data[REG_C] &= ~(REG_C_IRQF | REG_C_PF | REG_C_AF | REG_C_UF);
|
||||
update_irq();
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_D:
|
||||
@ -560,33 +637,11 @@ uint8_t mc146818_device::read_direct(offs_t offset)
|
||||
break;
|
||||
}
|
||||
|
||||
LOG("mc146818_port_r(): offset=0x%02x data=0x%02x\n", offset, data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// write - I/O handler for writing
|
||||
//-------------------------------------------------
|
||||
|
||||
void mc146818_device::write(offs_t offset, uint8_t data)
|
||||
void mc146818_device::internal_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0:
|
||||
m_index = data % data_size();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
write_direct(m_index, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void mc146818_device::write_direct(offs_t offset, uint8_t data)
|
||||
{
|
||||
LOG("mc146818_port_w(): offset=0x%02x data=0x%02x\n", offset, data);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case REG_SECONDS:
|
||||
|
@ -27,8 +27,8 @@ public:
|
||||
// callbacks
|
||||
auto irq() { return m_write_irq.bind(); }
|
||||
|
||||
// The MC146818 doesn't have century support, but when syncing the date & time at startup we can optionally store the century.
|
||||
void set_century_index(int century_index) { m_century_index = century_index; }
|
||||
// The MC146818 doesn't have century support (some variants do), but when syncing the date & time at startup we can optionally store the century.
|
||||
void set_century_index(int century_index) { assert(!century_count_enabled()); m_century_index = century_index; }
|
||||
|
||||
// The MC146818 doesn't have UTC support, but when syncing the data & time at startup we can use UTC instead of local time.
|
||||
void set_use_utc(bool use_utc) { m_use_utc = use_utc; }
|
||||
@ -62,7 +62,13 @@ protected:
|
||||
static constexpr unsigned char ALARM_DONTCARE = 0xc0;
|
||||
static constexpr unsigned char HOURS_PM = 0x80;
|
||||
|
||||
virtual int data_size() { return 64; }
|
||||
virtual int data_size() const { return 64; }
|
||||
virtual int data_logical_size() const { return data_size(); }
|
||||
virtual bool century_count_enabled() const { return false; }
|
||||
|
||||
virtual void internal_set_address(uint8_t address);
|
||||
virtual uint8_t internal_read(offs_t offset);
|
||||
virtual void internal_write(offs_t offset, uint8_t data);
|
||||
|
||||
enum
|
||||
{
|
||||
@ -120,33 +126,35 @@ protected:
|
||||
};
|
||||
|
||||
// internal helpers
|
||||
int to_ram(int a);
|
||||
int from_ram(int a);
|
||||
int to_ram(int a) const;
|
||||
int from_ram(int a) const;
|
||||
void set_base_datetime();
|
||||
void update_irq();
|
||||
void update_timer();
|
||||
virtual int get_timer_bypass();
|
||||
int get_seconds();
|
||||
virtual int get_timer_bypass() const;
|
||||
int get_seconds() const;
|
||||
void set_seconds(int seconds);
|
||||
int get_minutes();
|
||||
int get_minutes() const;
|
||||
void set_minutes(int minutes);
|
||||
int get_hours();
|
||||
int get_hours() const;
|
||||
void set_hours(int hours);
|
||||
int get_dayofweek();
|
||||
int get_dayofweek() const;
|
||||
void set_dayofweek(int dayofweek);
|
||||
int get_dayofmonth();
|
||||
int get_dayofmonth() const;
|
||||
void set_dayofmonth(int dayofmonth);
|
||||
int get_month();
|
||||
int get_month() const;
|
||||
void set_month(int month);
|
||||
int get_year();
|
||||
int get_year() const;
|
||||
void set_year(int year);
|
||||
int get_century() const;
|
||||
void set_century(int year);
|
||||
|
||||
optional_memory_region m_region;
|
||||
|
||||
// internal state
|
||||
|
||||
uint8_t m_index;
|
||||
std::vector<uint8_t> m_data;
|
||||
std::unique_ptr<uint8_t[]> m_data;
|
||||
|
||||
attotime m_last_refresh;
|
||||
|
||||
|
@ -46,7 +46,7 @@ Some debug tricks (let's test this CPU as more as possible):
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/mc68hc11/mc68hc11.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/ds17x85.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "video/mc6845.h"
|
||||
#include "emupal.h"
|
||||
@ -61,7 +61,10 @@ public:
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_gfxdecode(*this, "gfxdecode"),
|
||||
m_palette(*this, "palette") { }
|
||||
m_palette(*this, "palette"),
|
||||
m_eeprom(*this, "eeprom")
|
||||
{
|
||||
}
|
||||
|
||||
void hitpoker(machine_config &config);
|
||||
|
||||
@ -74,8 +77,6 @@ private:
|
||||
std::unique_ptr<uint8_t[]> m_videoram;
|
||||
std::unique_ptr<uint8_t[]> m_paletteram;
|
||||
std::unique_ptr<uint8_t[]> m_colorram;
|
||||
uint8_t m_eeprom_data[0x1000];
|
||||
uint16_t m_eeprom_index;
|
||||
|
||||
DECLARE_READ8_MEMBER(hitpoker_vram_r);
|
||||
DECLARE_WRITE8_MEMBER(hitpoker_vram_w);
|
||||
@ -83,19 +84,14 @@ private:
|
||||
DECLARE_WRITE8_MEMBER(hitpoker_cram_w);
|
||||
DECLARE_READ8_MEMBER(hitpoker_paletteram_r);
|
||||
DECLARE_WRITE8_MEMBER(hitpoker_paletteram_w);
|
||||
DECLARE_READ8_MEMBER(rtc_r);
|
||||
DECLARE_WRITE8_MEMBER(eeprom_offset_w);
|
||||
DECLARE_WRITE8_MEMBER(eeprom_w);
|
||||
DECLARE_READ8_MEMBER(eeprom_r);
|
||||
DECLARE_READ8_MEMBER(hitpoker_pic_r);
|
||||
DECLARE_WRITE8_MEMBER(hitpoker_pic_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(hitpoker_irq);
|
||||
DECLARE_READ8_MEMBER(irq_clear_r);
|
||||
virtual void video_start() override;
|
||||
uint32_t screen_update_hitpoker(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
required_device<mc68hc11_cpu_device> m_maincpu;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<palette_device> m_palette;
|
||||
required_shared_ptr<uint8_t> m_eeprom;
|
||||
void hitpoker_map(address_map &map);
|
||||
};
|
||||
|
||||
@ -193,38 +189,6 @@ WRITE8_MEMBER(hitpoker_state::hitpoker_paletteram_w)
|
||||
m_palette->set_pen_color(offset, pal5bit(r), pal6bit(g), pal5bit(b));
|
||||
}
|
||||
|
||||
READ8_MEMBER(hitpoker_state::rtc_r)
|
||||
{
|
||||
return 0x80; //kludge it for now
|
||||
}
|
||||
|
||||
|
||||
/* tests 0x180, what EEPROM is this one??? it seems to access up to 4KB */
|
||||
WRITE8_MEMBER(hitpoker_state::eeprom_offset_w)
|
||||
{
|
||||
if (offset == 0)
|
||||
m_eeprom_index = (m_eeprom_index & 0xf00) | (data & 0xff);
|
||||
else
|
||||
m_eeprom_index = (m_eeprom_index & 0x0ff) | (data << 8 & 0xf00);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(hitpoker_state::eeprom_w)
|
||||
{
|
||||
// is 0xbe53 the right address?
|
||||
m_eeprom_data[m_eeprom_index] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(hitpoker_state::eeprom_r)
|
||||
{
|
||||
/*** hack to make it boot ***/
|
||||
int ret = ((m_eeprom_index & 0x1f) == 0x1f) ? 1 : 0;
|
||||
m_eeprom_index++;
|
||||
return ret;
|
||||
/*** ***/
|
||||
|
||||
// FIXME: never executed
|
||||
//return m_eeprom_data[m_eeprom_index & 0xfff];
|
||||
}
|
||||
|
||||
READ8_MEMBER(hitpoker_state::hitpoker_pic_r)
|
||||
{
|
||||
@ -259,33 +223,15 @@ READ8_MEMBER(hitpoker_state::test_r)
|
||||
}
|
||||
#endif
|
||||
|
||||
WRITE_LINE_MEMBER(hitpoker_state::hitpoker_irq)
|
||||
{
|
||||
if (state)
|
||||
m_maincpu->set_input_line(MC68HC11_IRQ_LINE, ASSERT_LINE);
|
||||
}
|
||||
|
||||
READ8_MEMBER(hitpoker_state::irq_clear_r)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
m_maincpu->set_input_line(MC68HC11_IRQ_LINE, CLEAR_LINE);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/* overlap empty rom addresses */
|
||||
void hitpoker_state::hitpoker_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0xbdff).rom();
|
||||
map(0x0000, 0xb5ff).rom();
|
||||
map(0xbf00, 0xffff).rom();
|
||||
|
||||
map(0x8000, 0xb5ff).rw(FUNC(hitpoker_state::hitpoker_vram_r), FUNC(hitpoker_state::hitpoker_vram_w));
|
||||
map(0xb600, 0xbdff).ram();
|
||||
map(0xbe0a, 0xbe0a).portr("IN0");
|
||||
map(0xbe0c, 0xbe0c).r(FUNC(hitpoker_state::irq_clear_r));
|
||||
map(0xbe0d, 0xbe0d).r(FUNC(hitpoker_state::rtc_r));
|
||||
map(0xbe0e, 0xbe0e).portr("IN1");
|
||||
map(0xbe50, 0xbe51).w(FUNC(hitpoker_state::eeprom_offset_w));
|
||||
map(0xbe53, 0xbe53).rw(FUNC(hitpoker_state::eeprom_r), FUNC(hitpoker_state::eeprom_w));
|
||||
map(0xb600, 0xbdff).ram().share("eeprom");
|
||||
map(0xbe00, 0xbe7f).rw("rtc", FUNC(ds17x85_device::read_direct), FUNC(ds17x85_device::write_direct));
|
||||
map(0xbe80, 0xbe80).w("crtc", FUNC(mc6845_device::address_w));
|
||||
map(0xbe81, 0xbe81).w("crtc", FUNC(mc6845_device::register_w));
|
||||
map(0xbe90, 0xbe91).rw("aysnd", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w));
|
||||
@ -320,58 +266,6 @@ static INPUT_PORTS_START( hitpoker )
|
||||
PORT_DIPSETTING( 0x00, "24KHz" )
|
||||
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
|
||||
|
||||
PORT_START("IN0")
|
||||
PORT_DIPNAME( 0x01, 0x01, "IN0" )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START("IN1")
|
||||
PORT_DIPNAME( 0x01, 0x01, "IN1" )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
|
||||
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
|
||||
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
|
||||
|
||||
PORT_START("DSW1")
|
||||
PORT_DIPNAME( 0x01, 0x01, "DSW1" )
|
||||
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
|
||||
@ -461,7 +355,8 @@ void hitpoker_state::hitpoker(machine_config &config)
|
||||
m_maincpu->out_pa_callback().set(FUNC(hitpoker_state::hitpoker_pic_w));
|
||||
m_maincpu->in_pe_callback().set_constant(0);
|
||||
|
||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
|
||||
ds17x85_device &rtc(DS17487(config, "rtc", 32768));
|
||||
rtc.irq().set_inputline(m_maincpu, MC68HC11_IRQ_LINE);
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
@ -475,7 +370,7 @@ void hitpoker_state::hitpoker(machine_config &config)
|
||||
crtc.set_screen("screen");
|
||||
crtc.set_show_border_area(false);
|
||||
crtc.set_char_width(8);
|
||||
crtc.out_vsync_callback().set(FUNC(hitpoker_state::hitpoker_irq));
|
||||
//crtc.out_vsync_callback().set(FUNC(hitpoker_state::hitpoker_irq));
|
||||
|
||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_hitpoker);
|
||||
PALETTE(config, m_palette).set_entries(0x800);
|
||||
@ -492,15 +387,18 @@ void hitpoker_state::init_hitpoker()
|
||||
{
|
||||
uint8_t *ROM = memregion("maincpu")->base();
|
||||
|
||||
// init nvram
|
||||
subdevice<nvram_device>("nvram")->set_base(m_eeprom_data, sizeof(m_eeprom_data));
|
||||
|
||||
ROM[0x1220] = 0x01; //patch eeprom write?
|
||||
ROM[0x1221] = 0x01;
|
||||
ROM[0x1222] = 0x01;
|
||||
|
||||
ROM[0x10c6] = 0x01;
|
||||
ROM[0x10c7] = 0x01; //patch the checksum routine
|
||||
|
||||
// must match RTC serial number
|
||||
m_eeprom[3] = 'M';
|
||||
m_eeprom[2] = 'A';
|
||||
m_eeprom[1] = 'M';
|
||||
m_eeprom[0] = 'E';
|
||||
}
|
||||
|
||||
ROM_START( hitpoker )
|
||||
|
@ -22,6 +22,7 @@ NOTE: The default Sgi O2 Keyboard (Model No. RT6856T, Part No. 121472-101-B,
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/mips/mips3.h"
|
||||
#include "machine/ds17x85.h"
|
||||
#include "machine/mace.h"
|
||||
#include "video/crime.h"
|
||||
|
||||
@ -78,8 +79,12 @@ void o2_state::o2(machine_config &config)
|
||||
m_maincpu->set_force_no_drc(true);
|
||||
|
||||
SGI_MACE(config, m_mace, m_maincpu);
|
||||
m_mace->rtc_read_callback().set("rtc", FUNC(ds17x85_device::read_direct));
|
||||
m_mace->rtc_write_callback().set("rtc", FUNC(ds17x85_device::write_direct));
|
||||
|
||||
SGI_CRIME(config, m_crime, m_maincpu);
|
||||
|
||||
DS1687(config, "rtc", 32768);
|
||||
}
|
||||
|
||||
ROM_START( o2 )
|
||||
|
@ -55,9 +55,17 @@ DEFINE_DEVICE_TYPE(SGI_MACE, mace_device, "sgimace", "SGI MACE")
|
||||
mace_device::mace_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SGI_MACE, tag, owner, clock)
|
||||
, m_maincpu(*this, finder_base::DUMMY_TAG)
|
||||
, m_rtc_read_callback(*this)
|
||||
, m_rtc_write_callback(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void mace_device::device_resolve_objects()
|
||||
{
|
||||
m_rtc_read_callback.resolve_safe(0);
|
||||
m_rtc_write_callback.resolve_safe();
|
||||
}
|
||||
|
||||
void mace_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_isa.m_ringbase_reset));
|
||||
@ -82,15 +90,12 @@ void mace_device::device_start()
|
||||
m_timer_msc = timer_alloc(TIMER_MSC);
|
||||
m_timer_ust->adjust(attotime::never);
|
||||
m_timer_msc->adjust(attotime::never);
|
||||
|
||||
save_item(NAME(m_rtc.m_unknown));
|
||||
}
|
||||
|
||||
void mace_device::device_reset()
|
||||
{
|
||||
memset(&m_isa, 0, sizeof(isa_t));
|
||||
memset(&m_ust_msc, 0, sizeof(ust_msc_t));
|
||||
memset(&m_rtc, 0, sizeof(rtc_t));
|
||||
|
||||
m_timer_ust->adjust(attotime::from_nsec(960), 0, attotime::from_nsec(960));
|
||||
m_timer_msc->adjust(attotime::from_msec(1), 0, attotime::from_msec(1));
|
||||
@ -117,7 +122,7 @@ void mace_device::map(address_map &map)
|
||||
map(0x00330000, 0x0033ffff).rw(FUNC(mace_device::i2c_r), FUNC(mace_device::i2c_w));
|
||||
map(0x00340000, 0x0034ffff).rw(FUNC(mace_device::ust_msc_r), FUNC(mace_device::ust_msc_w));
|
||||
map(0x00380000, 0x0039ffff).rw(FUNC(mace_device::isa_ext_r), FUNC(mace_device::isa_ext_w));
|
||||
map(0x003a0000, 0x003a3fff).rw(FUNC(mace_device::rtc_r), FUNC(mace_device::rtc_w));
|
||||
map(0x003a0000, 0x003a7fff).rw(FUNC(mace_device::rtc_r), FUNC(mace_device::rtc_w));
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
@ -415,36 +420,20 @@ WRITE64_MEMBER(mace_device::isa_ext_w)
|
||||
|
||||
READ64_MEMBER(mace_device::rtc_r)
|
||||
{
|
||||
uint64_t ret = 0ULL;
|
||||
switch (offset)
|
||||
{
|
||||
case 0x3f00/8:
|
||||
ret = m_rtc.m_unknown;
|
||||
LOGMASKED(LOG_READ_RTC, "%s: MACE: RTC: Unknown Read: %08x = %08x%08x & %08x%08x\n", machine().describe_context(), 0x1f3a0000 + offset*8
|
||||
, (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_READ_RTC, "%s: MACE: RTC: Unknown Read: %08x = %08x%08x & %08x%08x\n", machine().describe_context()
|
||||
, 0x1f3a0000 + offset*8, (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
break;
|
||||
}
|
||||
uint64_t ret = m_rtc_read_callback(offset >> 5);
|
||||
|
||||
LOGMASKED(LOG_READ_RTC, "%s: MACE: RTC Read: %08x (register %02x) = %08x%08x & %08x%08x\n", machine().describe_context()
|
||||
, 0x1f3a0000 + offset*8, offset >> 5, (uint32_t)(ret >> 32), (uint32_t)ret, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE64_MEMBER(mace_device::rtc_w)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x3f00/8:
|
||||
LOGMASKED(LOG_WRITE_RTC, "%s: MACE: RTC: Unknown Write: %08x = %08x%08x & %08x%08x\n", machine().describe_context(), 0x1f3a0000 + offset*8
|
||||
, (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
m_rtc.m_unknown = data;
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_WRITE_RTC, "%s: MACE: RTC: Unknown Write: %08x = %08x%08x & %08x%08x\n", machine().describe_context(), 0x1f3a0000 + offset*8
|
||||
, (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
return;
|
||||
}
|
||||
LOGMASKED(LOG_WRITE_RTC, "%s: MACE: RTC Write: %08x (register %02x) = %08x%08x & %08x%08x\n", machine().describe_context(), 0x1f3a0000 + offset*8
|
||||
, offset >> 5, (uint32_t)(data >> 32), (uint32_t)data, (uint32_t)(mem_mask >> 32), (uint32_t)mem_mask);
|
||||
|
||||
m_rtc_write_callback(offset >> 5, data & 0xff);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
|
@ -25,9 +25,13 @@ public:
|
||||
|
||||
mace_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
auto rtc_read_callback() { return m_rtc_read_callback.bind(); }
|
||||
auto rtc_write_callback() { return m_rtc_write_callback.bind(); }
|
||||
|
||||
void map(address_map &map);
|
||||
|
||||
protected:
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
@ -67,6 +71,9 @@ protected:
|
||||
|
||||
required_device<mips3_device> m_maincpu;
|
||||
|
||||
devcb_read8 m_rtc_read_callback;
|
||||
devcb_write8 m_rtc_write_callback;
|
||||
|
||||
enum
|
||||
{
|
||||
ISA_INT_COMPARE1 = 0x2000,
|
||||
@ -98,19 +105,11 @@ protected:
|
||||
uint64_t m_vout_msc_ust;
|
||||
};
|
||||
|
||||
// DS17287 RTC; proper hookup is unknown
|
||||
struct rtc_t
|
||||
{
|
||||
uint64_t m_unknown;
|
||||
};
|
||||
|
||||
isa_t m_isa;
|
||||
|
||||
ust_msc_t m_ust_msc;
|
||||
emu_timer *m_timer_ust;
|
||||
emu_timer *m_timer_msc;
|
||||
|
||||
rtc_t m_rtc;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SGI_MACE, mace_device)
|
||||
|
Loading…
Reference in New Issue
Block a user