summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/i8291a.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/i8291a.h')
-rw-r--r--src/devices/machine/i8291a.h415
1 files changed, 415 insertions, 0 deletions
diff --git a/src/devices/machine/i8291a.h b/src/devices/machine/i8291a.h
new file mode 100644
index 00000000000..72561161a9b
--- /dev/null
+++ b/src/devices/machine/i8291a.h
@@ -0,0 +1,415 @@
+// license:BSD-3-Clause
+// copyright-holders: Sven Schnelle
+/*********************************************************************
+
+ i8291a.h
+
+ I8291A GPIB controller
+
+*********************************************************************/
+
+#ifndef MAME_MACHINE_I8291A_H
+#define MAME_MACHINE_I8291A_H
+
+
+#pragma once
+
+
+#define MCFG_I8291A_INT_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_int_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_DREQ_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_dreq_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_TRIG_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_trig_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_DIO_READ_CB(_read) \
+ downcast<i8291a_device &>(*device).set_dio_read_cb(DEVCB_##_read);
+
+#define MCFG_I8291A_DIO_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_dio_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_EOI_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_eoi_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_DAV_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_dav_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_NRFD_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_nrfd_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_NDAC_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_ndac_write_cb(DEVCB_##_write);
+
+#define MCFG_I8291A_SRQ_WRITE_CB(_write) \
+ downcast<i8291a_device &>(*device).set_srq_write_cb(DEVCB_##_write);
+
+
+class i8291a_device : public device_t
+{
+public:
+ // construction/destruction
+ i8291a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ template <class Object> devcb_base& set_int_write_cb(Object &&cb)
+ { return m_int_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_dreq_write_cb(Object &&cb)
+ { return m_dreq_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_trig_write_cb(Object &&cb)
+ { return m_trig_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_eoi_write_cb(Object &&cb)
+ { return m_eoi_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_dav_write_cb(Object &&cb)
+ { return m_dav_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_nrfd_write_cb(Object &&cb)
+ { return m_nrfd_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_ndac_write_cb(Object &&cb)
+ { return m_ndac_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_srq_write_cb(Object &&cb)
+ { return m_srq_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_dio_write_cb(Object &&cb)
+ { return m_dio_write_func.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> devcb_base& set_dio_read_cb(Object &&cb)
+ { return m_dio_read_func.set_callback(std::forward<Object>(cb)); }
+
+ // Signal inputs
+ DECLARE_WRITE_LINE_MEMBER(reset_w);
+ DECLARE_WRITE_LINE_MEMBER(dack_w);
+
+ // signal output
+ devcb_write_line m_int_write_func;
+ devcb_write_line m_dreq_write_func;
+ devcb_write_line m_trig_write_func;
+ devcb_write_line m_eoi_write_func;
+ devcb_write_line m_dav_write_func;
+ devcb_write_line m_nrfd_write_func;
+ devcb_write_line m_ndac_write_func;
+ devcb_write_line m_srq_write_func;
+
+ devcb_write8 m_dio_write_func;
+ devcb_read8 m_dio_read_func;
+
+ void set_dav(bool state);
+ void set_nrfd(bool state);
+ void set_ndac(bool state);
+ void set_eoi(bool state);
+ void set_srq(bool state);
+
+ // GPIB port
+ DECLARE_WRITE_LINE_MEMBER(eoi_w);
+ DECLARE_WRITE_LINE_MEMBER(dav_w);
+ DECLARE_WRITE_LINE_MEMBER(nrfd_w);
+ DECLARE_WRITE_LINE_MEMBER(ndac_w);
+ DECLARE_WRITE_LINE_MEMBER(ifc_w);
+ DECLARE_WRITE_LINE_MEMBER(srq_w);
+ DECLARE_WRITE_LINE_MEMBER(atn_w);
+ DECLARE_WRITE_LINE_MEMBER(ren_w);
+ DECLARE_WRITE8_MEMBER(dio_w);
+
+ // register r/w functions
+
+ DECLARE_WRITE8_MEMBER(dout_w);
+ DECLARE_WRITE8_MEMBER(ie1_w);
+ DECLARE_WRITE8_MEMBER(ie2_w);
+ DECLARE_WRITE8_MEMBER(spoll_mode_w);
+ DECLARE_WRITE8_MEMBER(addr_mode_w);
+ DECLARE_WRITE8_MEMBER(aux_mode_w);
+ DECLARE_WRITE8_MEMBER(addr01_w);
+ DECLARE_WRITE8_MEMBER(eos_w);
+
+ DECLARE_READ8_MEMBER(din_r);
+ DECLARE_READ8_MEMBER(ints1_r);
+ DECLARE_READ8_MEMBER(ints2_r);
+ DECLARE_READ8_MEMBER(spoll_stat_r);
+ DECLARE_READ8_MEMBER(addr_stat_r);
+ DECLARE_READ8_MEMBER(cpt_r);
+ DECLARE_READ8_MEMBER(addr0_r);
+ DECLARE_READ8_MEMBER(addr1_r);
+ void map(address_map &map);
+
+private:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ void update_int(void);
+ void handle_command(void);
+ void run_fsm();
+ void run_sh_fsm();
+ void run_ah_fsm();
+ void run_dt_fsm();
+ void run_dc_fsm();
+ void run_l_fsm();
+ void run_lp_fsm();
+ void run_t_fsm();
+ void run_tp_fsm();
+ void run_tsp_fsm();
+ void run_sp_fsm();
+ void run_pp_fsm();
+ void run_rl_fsm();
+
+ // registers
+
+ uint8_t m_din;
+ uint8_t m_dout;
+ uint8_t m_ints1;
+ uint8_t m_ints2;
+ uint8_t m_ie1;
+ uint8_t m_ie2;
+ uint8_t m_address0;
+ uint8_t m_address1;
+ uint8_t m_eos;
+ uint8_t m_spoll_mode;
+ uint8_t m_address_mode;
+ uint8_t m_address_status;
+ uint8_t m_cpt;
+
+ uint8_t m_auxa;
+ uint8_t m_auxb;
+
+ bool m_atn;
+ bool m_ren;
+ bool m_nrfd;
+ bool m_ndac;
+ bool m_dav;
+ bool m_srq;
+ bool m_ifc;
+ bool m_eoi;
+ uint8_t m_dio;
+
+ bool m_nrfd_out;
+ bool m_ndac_out;
+ bool m_dav_out;
+ bool m_srq_out;
+ bool m_eoi_out;
+
+ // internal signals
+
+ bool m_pon;
+ bool m_rdy;
+ bool m_lpe;
+ bool m_ist;
+ bool m_rtl;
+ bool m_apt_flag;
+ bool m_cpt_flag;
+ bool m_din_flag;
+ bool m_nba;
+
+ bool m_pp_sense;
+ bool m_pp_line;
+
+ bool m_send_eoi;
+
+ static constexpr int REG_INTS1_BI = (1 << 0);
+ static constexpr int REG_INTS1_BO = (1 << 1);
+ static constexpr int REG_INTS1_ERR = (1 << 2);
+ static constexpr int REG_INTS1_DEC = (1 << 3);
+ static constexpr int REG_INTS1_END = (1 << 4);
+ static constexpr int REG_INTS1_GET = (1 << 5);
+ static constexpr int REG_INTS1_APT = (1 << 6);
+ static constexpr int REG_INTS1_CPT = (1 << 7);
+
+ static constexpr int REG_INTS2_ADSC = (1 << 0);
+ static constexpr int REG_INTS2_REMC = (1 << 1);
+ static constexpr int REG_INTS2_LLOC = (1 << 2);
+ static constexpr int REG_INTS2_SPC = (1 << 3);
+ static constexpr int REG_INTS2_REM = (1 << 4);
+ static constexpr int REG_INTS2_LLO = (1 << 5);
+ static constexpr int REG_INTS2_SPAS = (1 << 6);
+ static constexpr int REG_INTS2_INT = (1 << 7);
+
+ static constexpr int REG_IE2_DMAI = (1 << 4);
+ static constexpr int REG_IE2_DMAO = (1 << 5);
+
+ static constexpr int REG_ADDRESS01_ARS = (1 << 7);
+ static constexpr int REG_ADDRESS0_INT = (1 << 7);
+ static constexpr int REG_ADDRESS_DT = (1 << 6);
+ static constexpr int REG_ADDRESS_DL = (1 << 5);
+
+ static constexpr int REG_ADDRESS_STATUS_MJMN = 1 << 0;
+ static constexpr int REG_ADDRESS_STATUS_TA = 1 << 1;
+ static constexpr int REG_ADDRESS_STATUS_LA = 1 << 2;
+ static constexpr int REG_ADDRESS_STATUS_TPAS = 1 << 3;
+ static constexpr int REG_ADDRESS_STATUS_LPAS = 1 << 4;
+ static constexpr int REG_ADDRESS_STATUS_EOI = 1 << 5;
+ static constexpr int REG_ADDRESS_STATUS_LON = 1 << 6;
+ static constexpr int REG_ADDRESS_STATUS_TON = 1 << 7;
+
+ static constexpr int REG_AUXB_CPT_ENABLE = 1 << 0;
+ static constexpr int REG_AUXB_EOI_SPAS_ENABLE = 1 << 1;
+ static constexpr int REG_AUXB_HS_TRANSFER = 1 << 2;
+ static constexpr int REG_AUXB_INT_ACTIVE_LOW = 1 << 3;
+ static constexpr int REG_AUXB_RFD_HOLDOFF_GET_DEC = 1 << 4;
+
+ static constexpr int REG_AUXA_RFD_HOLDOFF_DATA = 1 << 0;
+ static constexpr int REG_AUXA_RFD_HOLDOFF_END = 1 << 1;
+ static constexpr int REG_AUXA_END_ON_EOS = 1 << 2;
+ static constexpr int REG_AUXA_EOI_ON_EOS = 1 << 3;
+ static constexpr int REG_AUXA_EOS_8BIT = 1 << 4;
+
+ // AUX CMDs
+ static constexpr int AUXCMD_IMMEDIATE_EXEC_PON = 0;
+ static constexpr int AUXCMD_CLEAR_PP = 1;
+ static constexpr int AUXCMD_CHIP_RESET = 2;
+ static constexpr int AUXCMD_FINISH_HANDSHAKE = 3;
+ static constexpr int AUXCMD_TRIGGER = 4;
+ static constexpr int AUXCMD_CLEAR_RTL = 5;
+ static constexpr int AUXCMD_SEND_EOI = 6;
+ static constexpr int AUXCMD_NON_VALID_SA = 7;
+ static constexpr int AUXCMD_PON = 8;
+ static constexpr int AUXCMD_SET_PP = 9;
+ static constexpr int AUXCMD_SET_RTL = 13;
+ static constexpr int AUXCMD_VALID_SA = 15;
+
+ // Interface commands
+ // TODO: stolen from tms9914, move to common header file. PHI also defines this
+
+ static constexpr uint8_t IFCMD_MASK = 0x7f; // Mask of valid bits in if. commands
+ static constexpr uint8_t IFCMD_ACG_MASK = 0x70; // Mask of ACG commands
+ static constexpr uint8_t IFCMD_ACG_VALUE = 0x00; // Value of ACG commands
+ static constexpr uint8_t IFCMD_UCG_MASK = 0x70; // Mask of UCG commands
+ static constexpr uint8_t IFCMD_UCG_VALUE = 0x10; // Value of UCG commands
+ static constexpr uint8_t IFCMD_GROUP_MASK = 0x60; // Mask of group id
+ static constexpr uint8_t IFCMD_LAG_VALUE = 0x20; // Value of LAG commands
+ static constexpr uint8_t IFCMD_TAG_VALUE = 0x40; // Value of TAG commands
+ static constexpr uint8_t IFCMD_SCG_VALUE = 0x60; // Value of SCG commands
+ static constexpr uint8_t IFCMD_GTL = 0x01; // Go to local
+ static constexpr uint8_t IFCMD_SDC = 0x04; // Selected device clear
+ static constexpr uint8_t IFCMD_GET = 0x08; // Group execute trigger
+ static constexpr uint8_t IFCMD_TCT = 0x09; // Take control
+ static constexpr uint8_t IFCMD_LLO = 0x11; // Local lock-out
+ static constexpr uint8_t IFCMD_DCL = 0x14; // Device clear
+ static constexpr uint8_t IFCMD_SPE = 0x18; // Serial poll enable
+ static constexpr uint8_t IFCMD_SPD = 0x19; // Serial poll disable
+ static constexpr uint8_t IFCMD_UNL = 0x3f; // Unlisten
+ static constexpr uint8_t IFCMD_UNT = 0x5f; // Untalk
+
+ enum class SourceHandshake {
+ SIDS,
+ SGNS,
+ SDYS,
+ STRS
+ };
+
+ enum class AcceptorHandshake {
+ AIDS,
+ ANRS,
+ ACRS,
+ AWNS,
+ ADYS,
+ ACDS
+ };
+
+ enum class TalkerState {
+ TIDS,
+ TADS,
+ SPAS,
+ TACS
+ };
+
+ enum class TalkerPrimaryState {
+ TPIS,
+ TPAS
+ };
+
+ enum class ListenerPrimaryState {
+ LPIS,
+ LPAS
+ };
+
+ enum class TalkerSerialPollState {
+ SPIS,
+ SPMS
+ };
+
+ enum class SerialPollState {
+ NPRS,
+ SRQS,
+ APRS
+ };
+
+ enum class ListenerState {
+ LIDS,
+ LADS,
+ LACS
+ };
+
+ enum class RemoteLocalState {
+ LOCS,
+ REMS,
+ RWLS,
+ LWLS
+ };
+
+ enum class ParallelPollState {
+ PPIS,
+ PPSS,
+ PPAS
+ };
+
+ enum class DeviceClearState {
+ DCIS,
+ DCAS
+ };
+
+ enum class DeviceTriggerState {
+ DTIS,
+ DTAS
+ };
+
+ const char *get_state_name(AcceptorHandshake state);
+ const char *get_state_name(SourceHandshake state);
+ const char *get_state_name(TalkerState state);
+ const char *get_state_name(TalkerPrimaryState state);
+ const char *get_state_name(TalkerSerialPollState state);
+ const char *get_state_name(ListenerState state);
+ const char *get_state_name(ListenerPrimaryState state);
+ const char *get_state_name(DeviceClearState state);
+ const char *get_state_name(DeviceTriggerState state);
+ const char *get_state_name(ParallelPollState state);
+ const char *get_state_name(SerialPollState state);
+ const char *get_state_name(RemoteLocalState state);
+
+ template<typename T> void update_state(T &name, T state, int timeout = 0)
+ {
+ if (name != state) {
+ m_state_changed = true;
+ //logerror("%s: %s -> %s\n", __FUNCTION__,
+ // get_state_name(name),
+ // get_state_name(state));
+ name = state;
+ }
+ }
+
+ SourceHandshake m_sh_state;
+ AcceptorHandshake m_ah_state;
+ TalkerState m_t_state;
+ TalkerPrimaryState m_tp_state;
+ TalkerSerialPollState m_tsp_state;
+ ListenerState m_l_state;
+ ListenerPrimaryState m_lp_state;
+ RemoteLocalState m_rl_state;
+ SerialPollState m_sp_state;
+ ParallelPollState m_pp_state;
+ DeviceClearState m_dc_state;
+ DeviceTriggerState m_dt_state;
+ bool m_state_changed;
+ bool m_ignore_ext_signals;
+ bool m_intr_out;
+ bool m_dreq_out;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(I8291A, i8291a_device)
+
+#endif // MAME_MACHINE_I8291A_H