diff --git a/.gitattributes b/.gitattributes index 0d046384aa2..c755f64f47c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -789,6 +789,8 @@ src/emu/machine/i8155.c svneol=native#text/plain src/emu/machine/i8155.h svneol=native#text/plain src/emu/machine/i8212.c svneol=native#text/plain src/emu/machine/i8212.h svneol=native#text/plain +src/emu/machine/i8214.c svneol=native#text/plain +src/emu/machine/i8214.h svneol=native#text/plain src/emu/machine/i8243.c svneol=native#text/plain src/emu/machine/i8243.h svneol=native#text/plain src/emu/machine/i8255a.c svneol=native#text/plain diff --git a/src/emu/emu.mak b/src/emu/emu.mak index 26df8ff0fac..d336f113876 100644 --- a/src/emu/emu.mak +++ b/src/emu/emu.mak @@ -171,6 +171,7 @@ EMUMACHINEOBJS = \ $(EMUMACHINE)/i2cmem.o \ $(EMUMACHINE)/i8155.o \ $(EMUMACHINE)/i8212.o \ + $(EMUMACHINE)/i8214.o \ $(EMUMACHINE)/i8243.o \ $(EMUMACHINE)/i8255a.o \ $(EMUMACHINE)/i8355.o \ diff --git a/src/emu/machine/i8214.c b/src/emu/machine/i8214.c new file mode 100644 index 00000000000..2535faeec39 --- /dev/null +++ b/src/emu/machine/i8214.c @@ -0,0 +1,239 @@ +/********************************************************************** + + Intel 8214 Priority Interrupt Controller emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "emu.h" +#include "i8214.h" +#include "machine/devhelpr.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define LOG 0 + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// devices +const device_type I8214 = i8214_device_config::static_alloc_device_config; + + + +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** + +GENERIC_DEVICE_CONFIG_SETUP(i8214, "I8214") + + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void i8214_device_config::device_config_complete() +{ + // inherit a copy of the static data + const i8214_interface *intf = reinterpret_cast(static_config()); + if (intf != NULL) + *static_cast(this) = *intf; + + // or initialize to defaults if none provided + else + { + memset(&m_out_int_func, 0, sizeof(m_out_int_func)); + memset(&m_out_enlg_func, 0, sizeof(m_out_enlg_func)); + } +} + + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +//------------------------------------------------- +// trigger_interrupt - +//------------------------------------------------- + +inline void i8214_device::trigger_interrupt(int level) +{ + if (LOG) logerror("I8214 '%s' Interrupt Level %u\n", tag(), level); + + m_a = level; + + // disable interrupts + m_int_dis = 1; + + // disable next level group + devcb_call_write_line(&m_out_enlg_func, 0); + + // toggle interrupt line + devcb_call_write_line(&m_out_int_func, ASSERT_LINE); + devcb_call_write_line(&m_out_int_func, CLEAR_LINE); +} + + +//------------------------------------------------- +// check_interrupt - +//------------------------------------------------- + +inline void i8214_device::check_interrupt() +{ + int level; + + if (m_int_dis || !m_etlg) return; + + for (level = 7; level >= 0; level--) + { + if (!BIT(m_r, 7 - level)) + { + if (m_sgs) + { + if (level > m_b) + { + trigger_interrupt(level); + } + } + else + { + trigger_interrupt(level); + } + } + } +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// i8214_device - constructor +//------------------------------------------------- + +i8214_device::i8214_device(running_machine &_machine, const i8214_device_config &config) + : device_t(_machine, config), + m_config(config) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void i8214_device::device_start() +{ + // resolve callbacks + devcb_resolve_write_line(&m_out_int_func, &m_config.m_out_int_func, this); + devcb_resolve_write_line(&m_out_enlg_func, &m_config.m_out_enlg_func, this); + + // register for state saving + save_item(NAME(m_inte)); + save_item(NAME(m_int_dis)); + save_item(NAME(m_a)); + save_item(NAME(m_b)); + save_item(NAME(m_r)); + save_item(NAME(m_sgs)); + save_item(NAME(m_etlg)); +} + + +//------------------------------------------------- +// a_r - +//------------------------------------------------- + +UINT8 i8214_device::a_r() +{ + UINT8 a = m_a & 0x07; + + if (LOG) logerror("I8214 '%s' A: %01x\n", tag(), a); + + return a; +} + + +//------------------------------------------------- +// b_w - +//------------------------------------------------- + +void i8214_device::b_w(UINT8 data) +{ + m_b = data & 0x07; + + if (LOG) logerror("I8214 '%s' B: %01x\n", tag(), m_b); + + // enable interrupts + m_int_dis = 0; + + // enable next level group + devcb_call_write_line(&m_out_enlg_func, 1); + + check_interrupt(); +} + + +//------------------------------------------------- +// r_w - +//------------------------------------------------- + +void i8214_device::r_w(UINT8 data) +{ + if (LOG) logerror("I8214 '%s' R: %02x\n", tag(), data); + + m_r = data; + + check_interrupt(); +} + + +//------------------------------------------------- +// sgs_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( i8214_device::sgs_w ) +{ + if (LOG) logerror("I8214 '%s' SGS: %u\n", tag(), state); + + m_sgs = state; + + check_interrupt(); +} + + +//------------------------------------------------- +// etlg_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( i8214_device::etlg_w ) +{ + if (LOG) logerror("I8214 '%s' ETLG: %u\n", tag(), state); + + m_etlg = state; +} + + +//------------------------------------------------- +// inte_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( i8214_device::inte_w ) +{ + if (LOG) logerror("I8214 '%s' INTE: %u\n", tag(), state); + + m_inte = state; +} diff --git a/src/emu/machine/i8214.h b/src/emu/machine/i8214.h new file mode 100644 index 00000000000..06e4a59ed94 --- /dev/null +++ b/src/emu/machine/i8214.h @@ -0,0 +1,129 @@ +/********************************************************************** + + Intel 8214 Priority Interrupt Controller emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +********************************************************************** + _____ _____ + _B0 1 |* \_/ | 24 Vcc + _B1 2 | | 23 _ECS + _B2 3 | | 22 _R7 + _SGS 4 | | 21 _R6 + _INT 5 | | 20 _R5 + _CLK 6 | 8214 | 19 _R4 + INTE 7 | | 18 _R3 + _A0 8 | | 17 _R2 + _A1 9 | | 16 _R1 + _A2 10 | | 15 _R0 + _ELR 11 | | 14 ENLG + GND 12 |_____________| 13 ETLG + +**********************************************************************/ + +#pragma once + +#ifndef __I8214__ +#define __I8214__ + +#include "emu.h" + + + +///************************************************************************* +// INTERFACE CONFIGURATION MACROS +///************************************************************************* + +#define MCFG_I8214_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, I8214, _clock) \ + MCFG_DEVICE_CONFIG(_config) + + +#define I8214_INTERFACE(name) \ + const i8214_interface (name) = + + + +///************************************************************************* +// TYPE DEFINITIONS +///************************************************************************* + +// ======================> i8214_interface + +struct i8214_interface +{ + devcb_write_line m_out_int_func; + devcb_write_line m_out_enlg_func; +}; + + +// ======================> i8214_device_config + +class i8214_device_config : public device_config, + public i8214_interface +{ + friend class i8214_device; + + // construction/destruction + i8214_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + +public: + // allocators + static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + virtual device_t *alloc_device(running_machine &machine) const; + +protected: + // device_config overrides + virtual void device_config_complete(); +}; + + + +// ======================> i8214_device + +class i8214_device : public device_t +{ + friend class i8214_device_config; + + // construction/destruction + i8214_device(running_machine &_machine, const i8214_device_config &_config); + +public: + DECLARE_WRITE_LINE_MEMBER( sgs_w ); + DECLARE_WRITE_LINE_MEMBER( etlg_w ); + DECLARE_WRITE_LINE_MEMBER( inte_w ); + + UINT8 a_r(); + void b_w(UINT8 data); + void r_w(UINT8 data); + +protected: + // device-level overrides + virtual void device_start(); + +private: + inline void trigger_interrupt(int level); + inline void check_interrupt(); + + devcb_resolved_write_line m_out_int_func; + devcb_resolved_write_line m_out_enlg_func; + + int m_inte; // interrupt enable + int m_int_dis; // interrupt disable flip-flop + int m_a; // request level + int m_b; // current status register + UINT8 m_r; // interrupt request latch + int m_sgs; // status group select + int m_etlg; // enable this level group + + const i8214_device_config &m_config; +}; + + +// device type definition +extern const device_type I8214; + + + +#endif