// license:BSD-3-Clause
// copyright-holders:F. Ulivi
/*********************************************************************
phi.h
HP PHI (Processor-to-Hpib-Interface) (1AA6-6x04)
*********************************************************************/
#ifndef MAME_MACHINE_PHI_H
#define MAME_MACHINE_PHI_H
class phi_device : public device_t
{
public:
// construction/destruction
phi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// See ieee488.h
enum phi_488_signal_t
{
PHI_488_EOI,
PHI_488_DAV,
PHI_488_NRFD,
PHI_488_NDAC,
PHI_488_IFC,
PHI_488_SRQ,
PHI_488_ATN,
PHI_488_REN,
PHI_488_SIGNAL_COUNT
};
// Set read and write callbacks to access DIO bus on IEEE-488
auto dio_read_cb() { return m_dio_read_func.bind(); }
auto dio_write_cb() { return m_dio_write_func.bind(); }
// Set write callbacks to access uniline signals on IEEE-488
auto eoi_write_cb() { return m_signal_wr_fns[ PHI_488_EOI ].bind(); }
auto dav_write_cb() { return m_signal_wr_fns[ PHI_488_DAV ].bind(); }
auto nrfd_write_cb() { return m_signal_wr_fns[ PHI_488_NRFD ].bind(); }
auto ndac_write_cb() { return m_signal_wr_fns[ PHI_488_NDAC ].bind(); }
auto ifc_write_cb() { return m_signal_wr_fns[ PHI_488_IFC ].bind(); }
auto srq_write_cb() { return m_signal_wr_fns[ PHI_488_SRQ ].bind(); }
auto atn_write_cb() { return m_signal_wr_fns[ PHI_488_ATN ].bind(); }
auto ren_write_cb() { return m_signal_wr_fns[ PHI_488_REN ].bind(); }
// Set write callback for INT signal
auto int_write_cb() { return m_int_write_func.bind(); }
// Set write callback for DMARQ signal
auto dmarq_write_cb() { return m_dmarq_write_func.bind(); }
// Set read callback for SYS_CNTRL signal
auto sys_cntrl_read_cb() { return m_sys_cntrl_read_func.bind(); }
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(bus_dio_w);
void set_ext_signal(phi_488_signal_t signal , int state);
// Register read/write
// Mapping of PHI register bits:
// Reg. bit PHI bit
// =================
// 15 0
// 14 1
// 13 =0=
// 12 =0=
// 11 =0=
// 10 =0=
// 9 =0=
// 8 =0=
// 7 8
// 6 9
// 5 10
// 4 11
// 3 12
// 2 13
// 1 14
// 0 15
DECLARE_WRITE16_MEMBER(reg16_w);
DECLARE_READ16_MEMBER(reg16_r);
DECLARE_WRITE8_MEMBER(reg8_w);
DECLARE_READ8_MEMBER(reg8_r);
protected:
phi_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
// Depth of inbound/outbound FIFOs
static constexpr unsigned FIFO_SIZE = 8;
devcb_read8 m_dio_read_func;
devcb_write8 m_dio_write_func;
devcb_write_line m_signal_wr_fns[ PHI_488_SIGNAL_COUNT ];
devcb_write_line m_int_write_func;
devcb_write_line m_dmarq_write_func;
devcb_read_line m_sys_cntrl_read_func;
bool m_int_line;
bool m_dmarq_line;
// Internal copy of bus signals
// These signals have the "right" polarity (i.e. the opposite of bus signals, 1=L)
uint8_t m_dio;
bool m_signals[ PHI_488_SIGNAL_COUNT ];
bool m_ext_signals[ PHI_488_SIGNAL_COUNT ];
bool m_no_recursion;
bool m_sys_controller;
bool m_loopback;
bool m_id_enabled;
// SH (Source Handshake) states
enum {
PHI_SH_SIDS, // & SIWS
PHI_SH_SGNS, // & SWNS
PHI_SH_SDYS,
PHI_SH_STRS
};
int m_sh_state;
// AH (Acceptor Handshake) states
enum {
PHI_AH_AIDS,
PHI_AH_ANRS,
PHI_AH_ACRS,
PHI_AH_ACDS,
PHI_AH_ACDS_FROZEN, // Non-standard state: IF CMD rejected because of even parity
PHI_AH_AWNS
};
int m_ah_state;
// T (Talker) states
enum {
PHI_T_TIDS,
PHI_T_TADS,
PHI_T_SPAS,
PHI_T_TACS,
// The following are non-standard states for IDENTIFY sequencing
PHI_T_ID1, // Addressed by secondary address
PHI_T_ID2, // Sending 1st byte
PHI_T_ID3, // Waiting to send 2nd byte
PHI_T_ID4, // Sending 2nd byte
PHI_T_ID5 // 2nd byte sent, end of sequence
};
int m_t_state;
bool m_t_spms; // False: SPIS, true: SPMS
// L (Listener) states
enum {
PHI_L_LIDS,
PHI_L_LADS,
PHI_L_LACS
};
int m_l_state;
// SR (Service Request) states
enum {
PHI_SR_NPRS,
PHI_SR_SRQS,
PHI_SR_APRS
};
int m_sr_state;
// RL (Remote Local) states
bool m_rl_rems; // false: LOCS, true: REMS
// PP (Parallel poll) states
enum {
PHI_PP_PPIS,
PHI_PP_PPSS,
PHI_PP_PPAS
};
int m_pp_state;
uint8_t m_ppr_msg;
bool m_s_sense;
// C (Controller) states
enum {
PHI_C_CIDS,
PHI_C_CADS,
PHI_C_CACS,
PHI_C_CPPS,
PHI_C_CSBS,
PHI_C_CSHS,
PHI_C_CAWS,
PHI_C_CTRS,
PHI_C_CSWS
};
int m_c_state;
// Secondary address decoder states
enum {
PHI_SA_NONE,
PHI_SA_PACS,
PHI_SA_TPAS,
PHI_SA_LPAS,
PHI_SA_UNT
};
int m_sa_state;
uint8_t m_be_counter;
uint16_t m_reg_status;
uint16_t m_reg_int_cond;
uint16_t m_reg_int_mask;
uint16_t m_reg_1st_id;
uint16_t m_reg_2nd_id;
uint16_t m_reg_control;
uint16_t m_reg_address;
util::fifo<uint16_t , FIFO_SIZE> m_fifo_in;
util::fifo<uint16_t , FIFO_SIZE> m_fifo_out;
typedef enum {
NBA_NONE,
NBA_CMD_FROM_OFIFO,
NBA_BYTE_FROM_OFIFO,
NBA_FROM_SPAS,
NBA_FROM_ID2,
NBA_FROM_ID4
} nba_origin_t;
int m_nba_origin;
// Timers
emu_timer *m_sh_dly_timer;
emu_timer *m_c_dly_timer;
void int_reg_w(offs_t offset , uint16_t data);
uint8_t get_dio(void);
void set_dio(uint8_t data);
bool get_signal(phi_488_signal_t signal);
void set_signal(phi_488_signal_t signal , bool state);
void pon_msg(void);
void update_488(void);
void update_fsm(void);
nba_origin_t nba_msg(uint8_t& new_byte , bool& new_eoi) const;
void clear_nba(nba_origin_t origin);
bool if_cmd_received(uint8_t byte);
bool byte_received(uint8_t byte , bool eoi);
void rx_n_data_freeze(uint16_t word);
bool ton_msg(void) const;
bool lon_msg(void) const;
bool odd_parity(uint8_t byte) const;
uint8_t my_address(void) const;
bool tcs_msg(void) const;
bool rpp_msg(void) const;
uint8_t get_pp_response();
bool controller_in_charge(void) const;
void configure_pp_response();
void update_pp();
void update_interrupt();
void update_dmarq();
};
// device type definition
DECLARE_DEVICE_TYPE(PHI, phi_device)
#endif // MAME_MACHINE_PHI_H