summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/sh/sh7604_bus.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/sh/sh7604_bus.cpp')
-rw-r--r--src/devices/cpu/sh/sh7604_bus.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/devices/cpu/sh/sh7604_bus.cpp b/src/devices/cpu/sh/sh7604_bus.cpp
new file mode 100644
index 00000000000..f4000a46300
--- /dev/null
+++ b/src/devices/cpu/sh/sh7604_bus.cpp
@@ -0,0 +1,162 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/***************************************************************************
+
+ SH7604 BUS Controller
+
+ Lies at 0xffffffe0-0xffffffff
+
+
+ TODO:
+ - Host CPU setter (is_slave and clock are needed);
+ - timer clock emulation;
+ - fix fatalerrors;
+ - bus control stuff, someday;
+
+***************************************************************************/
+
+#include "emu.h"
+#include "sh7604_bus.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// device type definition
+DEFINE_DEVICE_TYPE(SH7604_BUS, sh7604_bus_device, "sh7604bus", "SH7604 BUS Controller")
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+READ16_MEMBER(sh7604_bus_device::bus_control_1_r)
+{
+ return (m_bcr1 & 0x1ff7) | (m_is_slave == true ? 0x8000 : 0);
+}
+
+WRITE16_MEMBER(sh7604_bus_device::bus_control_1_w)
+{
+ COMBINE_DATA(&m_bcr1);
+ if(m_bcr1 & 0x1000) // ENDIAN
+ throw emu_fatalerror("%s: enabled little endian for Area 2\n", tag());
+ if(m_bcr1 & 0x0800) // PSHR
+ throw emu_fatalerror("%s: enabled partial space share mode\n", tag());
+}
+
+READ16_MEMBER(sh7604_bus_device::bus_control_2_r) { return m_bcr2 & 0x00fc; }
+WRITE16_MEMBER(sh7604_bus_device::bus_control_2_w)
+{
+ COMBINE_DATA(&m_bcr2);
+ if(m_bcr2 != 0x00fc)
+ throw emu_fatalerror("%s: unexpected bus size register set %04x\n", tag(),data);
+}
+
+READ16_MEMBER(sh7604_bus_device::wait_control_r) { return m_wcr; }
+WRITE16_MEMBER(sh7604_bus_device::wait_control_w) { COMBINE_DATA(&m_wcr); }
+
+READ16_MEMBER(sh7604_bus_device::memory_control_r) { return m_mcr & 0xfefc; }
+WRITE16_MEMBER(sh7604_bus_device::memory_control_w) { COMBINE_DATA(&m_mcr); }
+
+READ16_MEMBER(sh7604_bus_device::refresh_timer_status_r)
+{
+ return m_rtcsr & 0x00f8;
+}
+
+WRITE16_MEMBER(sh7604_bus_device::refresh_timer_control_w)
+{
+ COMBINE_DATA(&m_rtcsr);
+
+ if(m_rtcsr & 0x40)
+ throw emu_fatalerror("%s: enabled timer irq register with clock setting = %02x\n",tag(),data & 0x38);
+}
+
+READ16_MEMBER(sh7604_bus_device::refresh_timer_counter_r)
+{
+ throw emu_fatalerror("%s: reading timer counter!\n",tag());
+ return 0;
+}
+
+WRITE16_MEMBER(sh7604_bus_device::refresh_timer_counter_w)
+{
+ throw emu_fatalerror("%s: writing timer counter %04x\n",tag(),data);
+ //COMBINE_DATA(&m_rtcnt);
+}
+
+READ16_MEMBER(sh7604_bus_device::refresh_timer_constant_r)
+{
+ return m_rtcor & 0xff;
+}
+
+WRITE16_MEMBER(sh7604_bus_device::refresh_timer_constant_w)
+{
+ COMBINE_DATA(&m_rtcor);
+}
+
+DEVICE_ADDRESS_MAP_START( bus_regs, 16, sh7604_bus_device )
+ AM_RANGE(0x00, 0x01) AM_READWRITE(bus_control_1_r, bus_control_1_w)
+ AM_RANGE(0x02, 0x03) AM_READWRITE(bus_control_2_r, bus_control_2_w)
+ AM_RANGE(0x04, 0x05) AM_READWRITE(wait_control_r, wait_control_w)
+ AM_RANGE(0x06, 0x07) AM_READWRITE(memory_control_r, memory_control_w)
+ AM_RANGE(0x08, 0x09) AM_READWRITE(refresh_timer_status_r, refresh_timer_control_w)
+ AM_RANGE(0x0a, 0x0b) AM_READWRITE(refresh_timer_counter_r, refresh_timer_counter_w)
+ AM_RANGE(0x0c, 0x0d) AM_READWRITE(refresh_timer_constant_r, refresh_timer_constant_w)
+// AM_RANGE(0x0e, 0x0f) unmapped, mirror?
+ADDRESS_MAP_END
+
+//-------------------------------------------------
+// sh7604_bus_device - constructor
+//-------------------------------------------------
+
+sh7604_bus_device::sh7604_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SH7604_BUS, tag, owner, clock)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sh7604_bus_device::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void sh7604_bus_device::device_reset()
+{
+ m_bcr1 = 0x03f0;
+ m_bcr2 = 0x00fc;
+ m_wcr = 0xaaff;
+ m_mcr = 0x0000;
+ m_rtcsr = 0x0000;
+ m_rtcor = 0x0000;
+}
+
+
+//**************************************************************************
+// READ/WRITE HANDLERS
+//**************************************************************************
+
+READ32_MEMBER( sh7604_bus_device::read )
+{
+ // 16 bit access only, TODO
+ return space.read_word(offset) & 0xffff;
+}
+
+WRITE32_MEMBER( sh7604_bus_device::write )
+{
+ // TODO: 8 bit access is invalid
+ // if accessing bits 16-31, one must write ID = 0xa55a
+ if(ACCESSING_BITS_16_31)
+ {
+ // throw fatalerror if something trips it, presumably the write is going to be ignored
+ if((data & 0xffff0000) != 0xa55a0000)
+ throw emu_fatalerror("%s: making bus write with ID signature = %04x!\n", tag(),data >> 16);
+ }
+
+ space.write_word(offset,data & 0xffff);
+}