// license:BSD-3-Clause // copyright-holders:Ryan Holtz /********************************************************************** SGI HPC3 "High-performance Peripheral Controller" emulation **********************************************************************/ #ifndef MAME_MACHINE_HPC3_H #define MAME_MACHINE_HPC3_H #pragma once #include "machine/hal2.h" class hpc3_device : public device_t, public device_memory_interface { public: enum pbus_space { AS_PIO0 = 0, AS_PIO1, AS_PIO2, AS_PIO3, AS_PIO4, AS_PIO5, AS_PIO6, AS_PIO7, AS_PIO8, AS_PIO9 }; hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); template hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&hal2_tag) : hpc3_device(mconfig, tag, owner, (uint32_t)0) { set_hal2_tag(std::forward(hal2_tag)); } template void set_gio64_space(T &&tag, int spacenum) { m_gio64_space.set_tag(std::forward(tag), spacenum); } template void set_hal2_tag(T &&tag) { m_hal2.set_tag(std::forward(tag)); } auto enet_rd_cb() { return m_enet_rd_cb.bind(); } auto enet_wr_cb() { return m_enet_wr_cb.bind(); } auto enet_rxrd_cb() { return m_enet_rxrd_cb.bind(); } auto enet_txwr_cb() { return m_enet_txwr_cb.bind(); } auto enet_d8_rd_cb() { return m_enet_d8_rd_cb.bind(); } auto enet_d8_wr_cb() { return m_enet_d8_wr_cb.bind(); } auto enet_reset_cb() { return m_enet_reset_cb.bind(); } auto enet_loopback_cb() { return m_enet_loopback_cb.bind(); } auto enet_intr_out_cb() { return m_enet_intr_out_cb.bind(); } template auto hd_rd_cb() { return m_hd_rd_cb[N].bind(); } template auto hd_wr_cb() { return m_hd_wr_cb[N].bind(); } template auto hd_dma_rd_cb() { return m_hd_dma_rd_cb[N].bind(); } template auto hd_dma_wr_cb() { return m_hd_dma_wr_cb[N].bind(); } template auto hd_reset_cb() { return m_hd_reset_cb[N].bind(); } auto bbram_rd_cb() { return m_bbram_rd_cb.bind(); } auto bbram_wr_cb() { return m_bbram_wr_cb.bind(); } auto eeprom_dati_cb() { return m_eeprom_dati_cb.bind(); } auto eeprom_dato_cb() { return m_eeprom_dato_cb.bind(); } auto eeprom_clk_cb() { return m_eeprom_clk_cb.bind(); } auto eeprom_cs_cb() { return m_eeprom_cs_cb.bind(); } auto eeprom_pre_cb() { return m_eeprom_pre_cb.bind(); } auto dma_complete_int_cb() { return m_dma_complete_int_cb.bind(); } void map(address_map &map); DECLARE_WRITE_LINE_MEMBER(enet_txrdy_w); DECLARE_WRITE_LINE_MEMBER(enet_rxrdy_w); DECLARE_WRITE_LINE_MEMBER(enet_rxdc_w); DECLARE_WRITE_LINE_MEMBER(enet_txret_w); DECLARE_WRITE_LINE_MEMBER(enet_intr_in_w); DECLARE_WRITE_LINE_MEMBER(scsi0_drq); DECLARE_WRITE_LINE_MEMBER(scsi1_drq); protected: virtual void device_resolve_objects() override; 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; virtual space_config_vector memory_space_config() const override; enum fifo_type_t : uint32_t { FIFO_PBUS, FIFO_SCSI0, FIFO_SCSI1, FIFO_ENET_RECV, FIFO_ENET_XMIT }; DECLARE_READ32_MEMBER(enet_r); DECLARE_WRITE32_MEMBER(enet_w); DECLARE_READ32_MEMBER(hd_enet_r); DECLARE_WRITE32_MEMBER(hd_enet_w); template DECLARE_READ32_MEMBER(hd_r); template DECLARE_WRITE32_MEMBER(hd_w); template DECLARE_READ32_MEMBER(fifo_r); template DECLARE_WRITE32_MEMBER(fifo_w); DECLARE_READ32_MEMBER(intstat_r); uint32_t misc_r(); void misc_w(uint32_t data); uint32_t eeprom_r(); void eeprom_w(uint32_t data); uint32_t pio_data_r(offs_t offset); void pio_data_w(offs_t offset, uint32_t data); DECLARE_READ32_MEMBER(pbusdma_r); DECLARE_WRITE32_MEMBER(pbusdma_w); DECLARE_READ32_MEMBER(dma_config_r); DECLARE_WRITE32_MEMBER(dma_config_w); DECLARE_READ32_MEMBER(pio_config_r); DECLARE_WRITE32_MEMBER(pio_config_w); uint32_t bbram_r(offs_t offset); void bbram_w(offs_t offset, uint32_t data); void do_pbus_dma(uint32_t channel); void do_scsi_dma(int channel); void dump_chain(uint32_t base); void fetch_chain(int channel); void decrement_chain(int channel); void scsi_fifo_flush(int channel); void scsi_drq(bool state, int channel); //void scsi_dma(int channel); static const device_timer_id TIMER_PBUS_DMA = 0; struct pbus_dma_t { bool m_active; uint32_t m_cur_ptr; uint32_t m_desc_ptr; uint32_t m_desc_flags; uint32_t m_next_ptr; uint32_t m_bytes_left; uint32_t m_config; uint32_t m_control; emu_timer *m_timer; }; enum { PBUS_CTRL_ENDIAN = 0x00000002, PBUS_CTRL_RECV = 0x00000004, PBUS_CTRL_FLUSH = 0x00000008, PBUS_CTRL_DMASTART = 0x00000010, PBUS_CTRL_LOAD_EN = 0x00000020, PBUS_CTRL_REALTIME = 0x00000040, PBUS_CTRL_HIGHWATER = 0x0000ff00, PBUS_CTRL_FIFO_BEG = 0x003f0000, PBUS_CTRL_FIFO_END = 0x3f000000, }; enum { PBUS_DMADESC_EOX = 0x80000000, PBUS_DMADESC_EOXP = 0x40000000, PBUS_DMADESC_XIE = 0x20000000, PBUS_DMADESC_IPG = 0x00ff0000, PBUS_DMADESC_TXD = 0x00008000, PBUS_DMADESC_BC = 0x00003fff, }; enum { HPC3_DMACTRL_IRQ = 0x01, HPC3_DMACTRL_ENDIAN = 0x02, HPC3_DMACTRL_DIR = 0x04, HPC3_DMACTRL_FLUSH = 0x08, HPC3_DMACTRL_ENABLE = 0x10, HPC3_DMACTRL_WRMASK = 0x20, }; enum { ENET_RECV = 0, ENET_XMIT = 1 }; const address_space_config m_pio_space_config[10]; required_address_space m_gio64_space; address_space *m_pio_space[10]; required_device m_hal2; devcb_read8 m_enet_rd_cb; devcb_write8 m_enet_wr_cb; devcb_read8 m_enet_rxrd_cb; devcb_write8 m_enet_txwr_cb; devcb_read_line m_enet_d8_rd_cb; devcb_write_line m_enet_d8_wr_cb; devcb_write_line m_enet_reset_cb; devcb_write_line m_enet_loopback_cb; devcb_write_line m_enet_intr_out_cb; devcb_read8 m_hd_rd_cb[2]; devcb_write8 m_hd_wr_cb[2]; devcb_read8 m_hd_dma_rd_cb[2]; devcb_write8 m_hd_dma_wr_cb[2]; devcb_write_line m_hd_reset_cb[2]; devcb_read8 m_bbram_rd_cb; devcb_write8 m_bbram_wr_cb; devcb_read_line m_eeprom_dati_cb; devcb_write_line m_eeprom_dato_cb; devcb_write_line m_eeprom_clk_cb; devcb_write_line m_eeprom_cs_cb; devcb_write_line m_eeprom_pre_cb; devcb_write_line m_dma_complete_int_cb; uint32_t m_intstat; uint32_t m_misc; uint32_t m_cpu_aux_ctrl; struct scsi_dma_t { uint32_t m_cbp; uint32_t m_nbdp; uint8_t m_ctrl; uint32_t m_bc; uint16_t m_count; uint32_t m_dmacfg; uint32_t m_piocfg; bool m_drq; bool m_big_endian; bool m_to_device; bool m_active; }; struct enet_dma_t { uint32_t m_cbp; uint32_t m_nbdp; uint32_t m_bc; uint32_t m_ctrl; uint32_t m_gio_fifo_ptr; uint32_t m_dev_fifo_ptr; }; enet_dma_t m_enet_dma[2]; uint32_t m_enet_reset; uint32_t m_enet_dmacfg; uint32_t m_enet_piocfg; scsi_dma_t m_scsi_dma[2]; pbus_dma_t m_pbus_dma[8]; uint32_t m_pio_config[10]; std::unique_ptr m_pbus_fifo; std::unique_ptr m_scsi_fifo[2]; std::unique_ptr m_enet_fifo[2]; }; DECLARE_DEVICE_TYPE(SGI_HPC3, hpc3_device) #endif // MAME_MACHINE_HPC3_H