mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
171 lines
5.1 KiB
C++
171 lines
5.1 KiB
C++
// 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
|
|
const device_type SH7604_BUS = &device_creator<sh7604_bus_device>;
|
|
|
|
|
|
//**************************************************************************
|
|
// 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);
|
|
}
|
|
|
|
static ADDRESS_MAP_START( bus_regs, AS_0, 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 clock)
|
|
: device_t(mconfig, SH7604_BUS, "sh7604_bus_longname", tag, owner, clock, "sh7604_bus", __FILE__),
|
|
device_memory_interface(mconfig, *this),
|
|
m_space_config("regs", ENDIANNESS_BIG, 16, 4, 0, nullptr, *ADDRESS_MAP_NAME(bus_regs))
|
|
{
|
|
}
|
|
|
|
|
|
const address_space_config *sh7604_bus_device::memory_space_config(address_spacenum spacenum) const
|
|
{
|
|
return (spacenum == AS_0) ? &m_space_config : nullptr;
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
// 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);
|
|
}
|