diff options
Diffstat (limited to 'src/mame/machine/namco06.cpp')
-rw-r--r-- | src/mame/machine/namco06.cpp | 270 |
1 files changed, 0 insertions, 270 deletions
diff --git a/src/mame/machine/namco06.cpp b/src/mame/machine/namco06.cpp deleted file mode 100644 index 37ec9688327..00000000000 --- a/src/mame/machine/namco06.cpp +++ /dev/null @@ -1,270 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Mike Harris, Aaron Giles -/*************************************************************************** - - Namco 06XX - - This chip is used as an interface to up to 4 other custom chips. - It signals IRQs to the custom MCUs when writes happen, and generates - NMIs to the controlling CPU to drive reads based on a clock. - - It uses a clock divider that's used to pulse the NMI and custom chip select - lines. - - The control register controls chip as such: the low 4 bits are chip selects - (active high), the 5th bit is read/!write, and the upper 3 bits are the - clock divide. - - SD0-SD7 are data I/O lines connecting to the controlling CPU - SEL selects either control (1) or data (0), usually connected to - an address line of the controlling CPU - /NMI is an NMI signal line for the controlling CPU - - ID0-ID7 are data I/O lines connecting to the other custom chips - /IO1-/IO4 are IRQ signal lines for each custom chip - - +------+ - [1]|1 28|Vcc - ID7|2 27|SD7 - ID6|3 26|SD6 - ID5|4 25|SD5 - ID4|5 24|SD4 - ID3|6 23|SD3 - ID2|7 22|SD2 - ID1|8 21|SD1 - ID0|9 20|SD0 - /IO1|10 19|/NMI - /IO2|11 18|/CS - /IO3|12 17|CLOCK - /IO4|13 16|R/W - GND|14 15|SEL - +------+ - - [1] on polepos, galaga, xevious, and bosco: connected to K3 of the 51xx - on bosco and xevious, connected to R8 of the 50xx - - Note that Xevious has a potential race condition at 0xE9. It checks if - the control register is 0x10 (chip disabled), then 4 instructions later - acts on that check. If an NMI occurs between, it can crash. - - - 06XX interface: - --------------- - Galaga 51XX ---- ---- 54XX - Bosconian (CPU board) 51XX ---- 50XX 54XX - Bosconian (Video board) 50XX 52XX ---- ---- - Xevious 51XX ---- 50XX 54XX - Dig Dug 51XX 53XX ---- ---- - Pole Position / PP II 51XX 53XX 52XX 54XX - - - Galaga writes: - control = 10(000), data = FF at startup - control = 71(011), read 3, control = 10 - control = A1(101), write 4, control = 10 - control = A8(101), write 12, control = 10 - - Xevious writes: - control = 10 at startup - control = A1(101), write 6, control = 10 - control = 71(011), read 3, control = 10 - control = 64(011), write 1, control = 10 - control = 74(011), read 4, control = 10 - control = 68(011), write 7, control = 10 - - Dig Dug writes: - control = 10(000), data = 10 at startup - control = A1(101), write 3, control = 10 - control = 71(011), read 3, control = 10 - control = D2(110), read 2, control = 10 - - Bosco writes: - control = 10(000), data = FF at startup - control = C8(110), write 17, control = 10 - control = 61(011), write 1, control = 10 - control = 71(011), read 3, control = 10 - control = 94(100), read 4, control = 10 - control = 64(011), write 1, control = 10 - control = 84(100), write 5, control = 10 - - - control = 34(001), write 1, control = 10 - -***************************************************************************/ - -#include "emu.h" -#include "machine/namco06.h" - -#define VERBOSE 0 -#include "logmacro.h" - - -TIMER_CALLBACK_MEMBER( namco_06xx_device::nmi_generate ) -{ - // This timer runs at twice the clock, since we do work on both the - // rising and falling edge. - // - // During reads, the first NMI pulse is supressed to give the chip a - // cycle to write. - // - // If the control register is written while CS is asserted, RW won't be - // changed until the next rising edge. - - if (m_rw_change && m_next_timer_state) - { - if (!m_rw_stretch) - { - m_rw[0](0, BIT(m_control, 4)); - m_rw[1](0, BIT(m_control, 4)); - m_rw[2](0, BIT(m_control, 4)); - m_rw[3](0, BIT(m_control, 4)); - m_rw_change = false; - } - } - - if (m_next_timer_state && !m_nmi_stretch ) - { - set_nmi(ASSERT_LINE); - } - else - { - set_nmi(CLEAR_LINE); - } - - m_chipsel[0](0, BIT(m_control, 0) && m_next_timer_state); - m_chipsel[1](0, BIT(m_control, 1) && m_next_timer_state); - m_chipsel[2](0, BIT(m_control, 2) && m_next_timer_state); - m_chipsel[3](0, BIT(m_control, 3) && m_next_timer_state); - - m_next_timer_state = !m_next_timer_state; - m_nmi_stretch = false; - m_rw_stretch = false; -} - -uint8_t namco_06xx_device::data_r(offs_t offset) -{ - uint8_t result = 0xff; - - if (!BIT(m_control, 4)) - { - logerror("%s: 06XX '%s' read in write mode %02x\n",machine().describe_context(),tag(),m_control); - return 0; - } - - if (BIT(m_control, 0)) result &= m_read[0](0); - if (BIT(m_control, 1)) result &= m_read[1](0); - if (BIT(m_control, 2)) result &= m_read[2](0); - if (BIT(m_control, 3)) result &= m_read[3](0); - - return result; -} - - -void namco_06xx_device::data_w(offs_t offset, uint8_t data) -{ - if (BIT(m_control, 4)) - { - logerror("%s: 06XX '%s' write in read mode %02x\n",machine().describe_context(),tag(),m_control); - return; - } - if (BIT(m_control, 0)) m_write[0](0, data); - if (BIT(m_control, 1)) m_write[1](0, data); - if (BIT(m_control, 2)) m_write[2](0, data); - if (BIT(m_control, 3)) m_write[3](0, data); -} - - -uint8_t namco_06xx_device::ctrl_r() -{ - return m_control; -} - -void namco_06xx_device::ctrl_w(uint8_t data) -{ - m_control = data; - - // The upper 3 control bits are the clock divider. - if ((m_control & 0xe0) == 0) - { - m_nmi_timer->adjust(attotime::never); - set_nmi(CLEAR_LINE); - m_chipsel[0](0, CLEAR_LINE); - m_chipsel[1](0, CLEAR_LINE); - m_chipsel[2](0, CLEAR_LINE); - m_chipsel[3](0, CLEAR_LINE); - // Setting this to true makes the next RW change not stretch. - m_next_timer_state = true; - } - else - { - m_rw_stretch = !m_next_timer_state; - m_rw_change = true; - m_next_timer_state = true; - m_nmi_stretch = BIT(m_control, 4); - // NMI is cleared immediately if its to be stretched. - if (m_nmi_stretch) set_nmi(CLEAR_LINE); - - uint8_t num_shifts = (m_control & 0xe0) >> 5; - uint8_t divisor = 1 << num_shifts; - // The next change should happen on the next clock falling edge. - // Xevious' race causes this to bootloopsif it isn't 0. - m_nmi_timer->adjust(attotime::zero, 0, attotime::from_hz(clock() / divisor) / 2); - } -} - - -void namco_06xx_device::set_nmi(int state) -{ - if (!m_nmicpu->suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE)) - { - m_nmicpu->set_input_line(INPUT_LINE_NMI, state); - } -} - - -DEFINE_DEVICE_TYPE(NAMCO_06XX, namco_06xx_device, "namco06", "Namco 06xx") - -namco_06xx_device::namco_06xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, NAMCO_06XX, tag, owner, clock) - , m_control(0) - , m_next_timer_state(false) - , m_nmi_stretch(false) - , m_rw_stretch(false) - , m_rw_change(false) - , m_nmicpu(*this, finder_base::DUMMY_TAG) - , m_chipsel(*this) - , m_rw(*this) - , m_read(*this) - , m_write(*this) -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void namco_06xx_device::device_start() -{ - m_chipsel.resolve_all_safe(); - m_rw.resolve_all_safe(); - m_read.resolve_all_safe(0xff); - m_write.resolve_all_safe(); - - /* allocate a timer */ - m_nmi_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(namco_06xx_device::nmi_generate),this)); - - save_item(NAME(m_control)); - save_item(NAME(m_next_timer_state)); - save_item(NAME(m_nmi_stretch)); - save_item(NAME(m_rw_stretch)); - save_item(NAME(m_rw_change)); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void namco_06xx_device::device_reset() -{ - m_control = 0; -} |