summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/interpro_ioga.h
blob: 56dc6995cc615349ad89174442cd490511bc4e5b (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                                      

                                    
 
            
 

                                            

                                                                                                                                
 
                           
         


                             
          
 
                             
         



















                                                                                              
          
 
                        
         


                                
          

       








                                                                                                                    
 
                                                                                                                                
 
                                               

                                  









                                                                               
                                                                              



                                                                                


                            
         




                                             
                                             
                                             

                                             


                                             
          

                                                                   
 
                         
         




                                   
 
                                                       
          

                                            
 

                                            
 








                                                                           
                          
         
                                                                     
 


                                                                         
 
                                                                  
                                                                                      
                                                                                            
 
                                                                           
                                                                                                                 
 
                                                                                                         
          























                                                                                                                             













                                         

                                           
 
                               








                                      
                                  





                                           



                                                              
 
                                                
 
                 

                                                                  






                                            

                                                                  
 

                                                                     









                                           

                                          
                                                             
                                                                        
 



                                             
 
                                              
                                                                   
 


                                        
                                           

                                       
 
                                     
                                                 
 
                                                       



                                          
                                                  
 
                                                     

                                     

                                     














                                                                           
        
                                                                                      
 
                                         

                                                

                                                                               
 
                                       
         


                                                      
                                          





                                                                            
          



                                                                                                  

                          

                        
                        


                            
                     
 

                                               
                            
         



                                    
 
                              

                                      

                                   


                                           
                               
 


                                                      

                            
                            

                              




                                      

                                                         
 

                          
                           
                        
 



                                      
                                
 
                                      
                     

                            
                          
 

                           








                                                                                                             

                                                               







                                                          

                                                                    














                                                                                           

                                                                       



                          
  
 



                                                                                                               
 
                                                    
 

                                                               







                                                          

                                                                    














                                                                                           

                                                                       










                                                                                                              
                                                    
 

                                                           

                                                               
 



                                                                        






                                            

                                                                  

 

                                                                          


                                                                    
          




                                                                










                                                          

                                                 
 








                                           

                                                 














                                                                                             

                                                                       
 






                                                                                                                              
        

                                             
                        
                        
                          








                            


                         
                                                      

                                                          
 
                                      
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay

#ifndef MAME_MACHINE_INTERPRO_IOGA_H
#define MAME_MACHINE_INTERPRO_IOGA_H

#pragma once

class interpro_ioga_device : public device_t
{
protected:
	interpro_ioga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	enum interrupt_type
	{
		INT_NONE = 0,
		INT_HARD = 1,
		INT_SOFT = 2,
	};

	enum interrupt_number
	{
		IRQ_SCSI     =  0, // external int  0 (offset 0x60)
		IRQ_FLOPPY   =  1, // external int  1 (offset 0x62)
		IRQ_PLOTTER  =  2, // external int  2 (offset 0x64)
		IRQ_SRXCBUS0 =  3, // external int  3 (offset 0x66)
		IRQ_SRXCBUS1 =  4, // external int  4 (offset 0x68)
		IRQ_SRXCBUS2 =  5, // external int  5 (offset 0x6a)
		IRQ_VB       =  6, // external int  6 (offset 0x6c)
		IRQ_7        =  7, // external int  7 (offset 0x6e)
		IRQ_CBUS3    =  8, // external int  8 (offset 0x70)
		IRQ_RTC      =  9, // external int  9 (offset 0x72)
		IRQ_60HZ     = 10, // external int 10 (offset 0x74)
		IRQ_MOUSE    = 11, // internal int  0 (offset 0x76)
		IRQ_TIMER0   = 12, // internal int  1 (offset 0x78)
		IRQ_TIMER1   = 13, // internal int  2 (offset 0x7a)
		IRQ_SERDMA   = 14, // internal int  3 (offset 0x7c) // Sapphire internal int 5
		IRQ_SERIAL   = 15, // external int 11 (offset 0x7e)
		IRQ_ETHERNET = 16, // external int 12 (offset 0x80)

		IRQ_TIMER2   = 17, // internal int  3 (offset 0x5c) // Sapphire only
		IRQ_TIMER3   = 18, // internal int  4 (offset 0x5e) // Sapphire only
	};

	enum dma_channel
	{
		DMA_PLOTTER = 0,
		DMA_SCSI    = 1,
		DMA_FLOPPY  = 2
	};

public:
	auto out_nmi_callback() { return m_out_nmi_func.bind(); }
	auto out_irq_callback() { return m_out_irq_func.bind(); }
	auto out_irq_vector_callback() { return m_out_irq_vector_func.bind(); }
	template <unsigned Chan> auto dma_r_callback() { return m_dma_channel[Chan].device_r.bind(); }
	template <unsigned Chan> auto dma_w_callback() { return m_dma_channel[Chan].device_w.bind(); }
	template <unsigned Chan> auto serial_dma_r_callback() { return m_serial_dma_channel[Chan].device_r.bind(); }
	template <unsigned Chan> auto serial_dma_w_callback() { return m_serial_dma_channel[Chan].device_w.bind(); }
	auto fdc_tc_callback() { return m_fdc_tc_func.bind(); }
	auto eth_ca_callback() { return m_eth_ca_func.bind(); }

	template <typename T> void set_memory(T &&tag, int spacenum) { m_memory_space.set_tag(std::forward<T>(tag), spacenum); }

	virtual void map(address_map &map) = 0;

	// interrupt request lines
	DECLARE_WRITE_LINE_MEMBER(ir0_w) { set_int_line(IRQ_SCSI, state); }
	DECLARE_WRITE_LINE_MEMBER(ir1_w) { set_int_line(IRQ_FLOPPY, state); }
	DECLARE_WRITE_LINE_MEMBER(ir2_w) { set_int_line(IRQ_PLOTTER, state); }
	DECLARE_WRITE_LINE_MEMBER(ir3_w) { set_int_line(IRQ_SRXCBUS0, state); }
	DECLARE_WRITE_LINE_MEMBER(ir4_w) { set_int_line(IRQ_SRXCBUS1, state); }
	DECLARE_WRITE_LINE_MEMBER(ir5_w) { set_int_line(IRQ_SRXCBUS2, state); }
	DECLARE_WRITE_LINE_MEMBER(ir6_w) { set_int_line(IRQ_VB, state); }
	DECLARE_WRITE_LINE_MEMBER(ir7_w) { set_int_line(IRQ_7, state); }
	DECLARE_WRITE_LINE_MEMBER(ir8_w) { set_int_line(IRQ_CBUS3, state); }
	DECLARE_WRITE_LINE_MEMBER(ir9_w) { set_int_line(IRQ_RTC, state); }
	//DECLARE_WRITE_LINE_MEMBER(ir10_w) { set_int_line(IRQ_60HZ, state); }
	DECLARE_WRITE_LINE_MEMBER(ir11_w) { set_int_line(IRQ_SERIAL, state); }
	DECLARE_WRITE_LINE_MEMBER(ir12_w) { set_int_line(IRQ_ETHERNET, state); }

	virtual IRQ_CALLBACK_MEMBER(acknowledge_interrupt);

	// interrupt control
	enum icr_mask
	{
		IRQ_NUMBER          = 0x000f,
		IRQ_LEVEL           = 0x00f0,
		IRQ_VECTOR          = 0x00ff,
		IRQ_FLAGS           = 0xff00,

		IRQ_PENDING         = 0x0100,
		IRQ_ENABLE          = 0x0200,
		IRQ_EDGE            = 0x0400,
		IRQ_NEGPOL          = 0x0800,
		IRQ_ENABLE_INT      = 0x1000,

		IRQ_ENABLE_SERDMA   = 0x0e00,
	};
	u16 hardint_r(offs_t offset) { return m_hwicr[offset]; }
	void hardint_w(offs_t offset, u16 data, u16 mem_mask = ~0);

	enum nmictrl_mask
	{
		NMI_ALL     = 0x01,
		NMI_ENABLE1 = 0x02,
		NMI_EDGE    = 0x04,
		NMI_NEGPOL  = 0x08,
		NMI_ENABLE2 = 0x10,

		NMI_IE      = NMI_ENABLE1 | NMI_ENABLE2
	};
	u8 nmictrl_r() { return m_nmictrl; }
	void nmictrl_w(u8 data);

	u8 softint_r() { return m_softint; }
	void softint_w(u8 data);

	// dma request lines
	DECLARE_WRITE_LINE_MEMBER(drq_plotter) { drq(state, DMA_PLOTTER); }
	DECLARE_WRITE_LINE_MEMBER(drq_scsi) { drq(state, DMA_SCSI); }
	DECLARE_WRITE_LINE_MEMBER(drq_floppy) { drq(state, DMA_FLOPPY); }
	DECLARE_WRITE_LINE_MEMBER(drq_serial0) { serial_drq(state, 0); }
	DECLARE_WRITE_LINE_MEMBER(drq_serial1) { serial_drq(state, 1); }
	DECLARE_WRITE_LINE_MEMBER(drq_serial2) { serial_drq(state, 2); }

	// dma control
	enum dma_ctrl_mask
	{
		DMA_CTRL_TCZERO  = 0x00000001, // transfer count zero

		DMA_CTRL_TAG     = 0x00000e00, // bus tag
		DMA_CTRL_BERR    = 0x00400000, // bus error
		DMA_CTRL_ERR     = 0x00800000, // checked for in scsi isr

		DMA_CTRL_ENABLE  = 0x01000000, // transfer enabled
		DMA_CTRL_VIRTUAL = 0x02000000, // virtual address translation required
		DMA_CTRL_DOUBLE  = 0x04000000, // double transfer size (double or quad quad)

		DMA_CTRL_WRITE   = 0x40000000, // memory to device transfer
		DMA_CTRL_QUAD    = 0x80000000, // select quad transfer size (quad quad when combined with double)

		DMA_CTRL_WMASK   = 0xfd000e00  // writable fields (quad not writable for floppy/plotter?)
	};
	u32 dma_plotter_r(offs_t offset) { return dma_r(offset, DMA_PLOTTER); }
	void dma_plotter_w(offs_t offset, u32 data, u32 mem_mask = ~0) { dma_w(offset, data, mem_mask, DMA_PLOTTER); }
	u32 dma_scsi_r(offs_t offset) { return dma_r(offset, DMA_SCSI); }
	void dma_scsi_w(offs_t offset, u32 data, u32 mem_mask = ~0) { dma_w(offset, data, mem_mask, DMA_SCSI); }
	u32 dma_floppy_r(offs_t offset) { return dma_r(offset, DMA_FLOPPY); }
	void dma_floppy_w(offs_t offset, u32 data, u32 mem_mask = ~0) { dma_w(offset, data, mem_mask, DMA_FLOPPY); }

	u32 serial_dma0_addr_r() { return serial_dma_addr_r(0); }
	void serial_dma0_addr_w(offs_t offset, u32 data, u32 mem_mask = ~0) { serial_dma_addr_w(offset, data, mem_mask, 0); }
	u32 serial_dma0_ctrl_r() { return serial_dma_ctrl_r(0); }
	void serial_dma0_ctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0) { serial_dma_ctrl_w(offset, data, mem_mask, 0); }

	u32 serial_dma1_addr_r() { return serial_dma_addr_r(1); }
	void serial_dma1_addr_w(offs_t offset, u32 data, u32 mem_mask = ~0) { serial_dma_addr_w(offset, data, mem_mask, 1); }
	u32 serial_dma1_ctrl_r() { return serial_dma_ctrl_r(1); }
	void serial_dma1_ctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0) { serial_dma_ctrl_w(offset, data, mem_mask, 1); }

	u32 serial_dma2_addr_r() { return serial_dma_addr_r(2); }
	void serial_dma2_addr_w(offs_t offset, u32 data, u32 mem_mask = ~0) { serial_dma_addr_w(offset, data, mem_mask, 2); }
	u32 serial_dma2_ctrl_r() { return serial_dma_ctrl_r(2); }
	void serial_dma2_ctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0) { serial_dma_ctrl_w(offset, data, mem_mask, 2); }

	u32 dma_plotter_eosl_r() { return m_dma_plotter_eosl; }
	void dma_plotter_eosl_w(u32 data) { m_dma_plotter_eosl = data ^ 0xffff0000; }

	// bus arbitration and control
	enum arbctl_mask
	{
		ARBCTL_BGR_ETHC = 0x0001,
		ARBCTL_BGR_SCSI = 0x0002,
		ARBCTL_BGR_PLOT = 0x0004,
		ARBCTL_BGR_FDC  = 0x0008,
		ARBCTL_BGR_SER0 = 0x0010,
		ARBCTL_BGR_SER1 = 0x0020,
		ARBCTL_BGR_SER2 = 0x0040,
		ARBCTL_BGR_ETHB = 0x0080,
		ARBCTL_BGR_ETHA = 0x0100
	};
	u16 arbctl_r() { return m_arbctl; }
	void arbctl_w(u16 data);

	enum error_businfo_mask
	{
		BINFO_CT     = 0x003f,
		BINFO_TAG    = 0x01c0,
		BINFO_BG     = 0x0e00,
		BINFO_BERR   = 0x1000,
		BINFO_MMBE   = 0x2000,
		BINFO_SNAPOK = 0x4000,
		BINFO_MSBE   = 0x8000
	};
	enum error_businfo_bg_mask
	{
		BINFO_BG_IOD      = 0x0200,
		BINFO_BG_ICAMMU   = 0x0400,
		BINFO_BG_DCAMMU   = 0x0800,
		BINFO_BG_SRMASTER = 0x0c00
	};
	u32 error_businfo_r();
	u32 error_address_r() { return m_error_address; }
	u32 bus_timeout_r() { return m_bus_timeout; }
	void bus_timeout_w(u32 data) { m_bus_timeout = data; }

	void bus_error(offs_t offset, u32 data);

	// timers
	u32 timer0_r(offs_t offset, u32 mem_mask = ~0);
	void timer0_w(offs_t offset, u32 data, u32 mem_mask = ~0);

	enum timer1_mask
	{
		TIMER1_COUNT   = 0x0000ffff,
		TIMER1_START   = 0x00010000,
		TIMER1_EXPIRED = 0x00020000
	};
	u32 timer1_r(offs_t offset, u32 mem_mask = ~0);
	void timer1_w(offs_t offset, u32 data, u32 mem_mask = ~0);

	u32 prescaler_r();
	void prescaler_w(offs_t offset, u32 data, u32 mem_mask = ~0);

	// mouse
	enum mouse_status_mask
	{
		MOUSE_YPOS    = 0x000000ff,
		MOUSE_XPOS    = 0x0000ff00,
		MOUSE_LBUTTON = 0x00010000,
		MOUSE_MBUTTON = 0x00020000,
		MOUSE_RBUTTON = 0x00040000,

		MOUSE_BUTTONS = 0x00070000
	};
	u32 mouse_status_r(offs_t offset, u32 mem_mask = ~0);
	void mouse_status_w(offs_t offset, u32 data, u32 mem_mask = ~0);

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;

	required_address_space m_memory_space;
	memory_access<32, 2, 0, ENDIANNESS_LITTLE>::cache m_memory;

	// callbacks
	devcb_write_line m_out_nmi_func;
	devcb_write_line m_out_irq_func;
	devcb_write8 m_out_irq_vector_func;
	devcb_write_line m_fdc_tc_func;
	devcb_write_line m_eth_ca_func;

	void set_nmi_line(int state);
	void set_int_line(int number, int state);

	virtual TIMER_CALLBACK_MEMBER(interrupt_check);
	TIMER_CALLBACK_MEMBER(dma);
	TIMER_CALLBACK_MEMBER(serial_dma);
	TIMER_CALLBACK_MEMBER(timer0);
	TIMER_CALLBACK_MEMBER(timer1);
	virtual TIMER_CALLBACK_MEMBER(timer_60hz);

	virtual TIMER_CALLBACK_MEMBER(eth_reset) = 0;

	emu_timer *m_interrupt_timer;
	emu_timer *m_eth_reset_timer;

	std::unique_ptr<u16 []> m_hwicr;
	u32 m_force_state;
	u8 m_softint;

	interrupt_type m_active_interrupt_type;
	u8 m_active_interrupt_number;

	void nmi(int state);
	void irq(int state, u8 ivec);
	u8 get_irq_vector() const { return m_irq_vector; }

	virtual u8 get_int_count() const { return 17; }
	virtual u8 get_reg_offset(u8 const number) const { return number; }
	virtual u8 get_int_number(u8 const offset) const { return offset; }

private:
	TIMER_CALLBACK_MEMBER(set_irq_vector) { m_out_irq_vector_func(m_irq_vector); }

	void drq(int state, int channel);
	void serial_drq(int state, int channel);

	u32 dma_r(offs_t offset, dma_channel channel) const;
	void dma_w(offs_t offset, u32 data, u32 mem_mask, dma_channel channel);

	enum serial_dma_ctrl_mask : u32
	{
		SDMA_COUNT   = 0x000000ff,
		SDMA_TAG     = 0x0000ff00, // bus tag?

		SDMA_TCZERO  = 0x00200000,

		SDMA_WRITE   = 0x01000000, // transfer from memory to device
		SDMA_ENABLE  = 0x02000000,
		SDMA_0400    = 0x04000000,

		SDMA_1000    = 0x10000000, // set on Sapphire systems?
	};
	u32 serial_dma_addr_r(int channel) const { return m_serial_dma_channel[channel].address; }
	void serial_dma_addr_w(offs_t offset, u32 data, u32 mem_mask, int channel);
	u32 serial_dma_ctrl_r(int channel) const { return m_serial_dma_channel[channel].control; }
	void serial_dma_ctrl_w(offs_t offset, u32 data, u32 mem_mask, int channel);

	// interrupt state
	int m_nmi_state;
	int m_irq_state;
	u8 m_irq_vector;
	u32 m_line_state;

	// interrupt control
	u8 m_nmictrl;

	// dma state
	static const int DMA_CHANNEL_COUNT = 3;
	struct dma_channel_t
	{
		u32 real_address;
		u32 virtual_address;
		u32 transfer_count;
		u32 control;

		int drq_state;
		devcb_read8 device_r;
		devcb_write8 device_w;

		const u16 arb_mask;
		const dma_channel channel;
		const char *const name;
	} m_dma_channel[DMA_CHANNEL_COUNT];
	u32 m_dma_plotter_eosl;

	// serial dma state
	static const int SERIAL_DMA_CHANNEL_COUNT = 3;
	struct serial_dma_channel_t
	{
		u32 address;
		u32 control;

		int drq_state;
		devcb_read8 device_r;
		devcb_write8 device_w;

		const u16 arb_mask;
		const int channel;
		const char *const name;
	} m_serial_dma_channel[SERIAL_DMA_CHANNEL_COUNT];

	// timers
	u8 m_timer0_count;
	u16 m_timer1_count;
	u32 m_prescaler;

	emu_timer *m_dma_timer;
	emu_timer *m_serial_dma_timer;
	emu_timer *m_timer0;
	emu_timer *m_timer1;
	emu_timer *m_timer_60hz;

	// bus arbitration and control
	u16 m_arbctl;
	u32 m_error_address;
	u32 m_error_businfo;
	u32 m_bus_timeout;

	// mouse
	u32 m_mouse_status;
};

class emerald_ioga_device : public interpro_ioga_device
{
public:
	emerald_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	virtual void map(address_map &map) override;

	void eth_w(offs_t offset, u16 data, u16 mem_mask = ~0);
	u16 eth_r(offs_t offset, u16 mem_mask = ~0);

protected:
	virtual TIMER_CALLBACK_MEMBER(eth_reset) override;

	enum eth_base_mask
	{
		ETH_BASE_MASK = 0xffe00000
	};
	u32 eth_base_r() { return m_eth_base; }
	void eth_base_w(offs_t offset, u32 data, u32 mem_mask = ~0);

	enum eth_control_mask
	{
		ETH_CA    = 0x0001, // channel attention
		ETH_FLUSH = 0x0002,
		ETH_BUF   = 0x0004,
		ETH_QUAD  = 0x0008,
		ETH_BERR  = 0x0010, // bus error
		ETH_PERR  = 0x0020, // parity error
		ETH_RESET = 0x0040,
		ETH_WTAG  = 0x0600,
		ETH_RTAG  = 0x3000,

		//ETH_MASK     = 0x4ff2  // channel attention and error bits not persistent
	};
	u16 eth_control_r() { return m_eth_control; }
	void eth_control_w(offs_t offset, u16 data, u16 mem_mask = ~0);

private:
	u32 m_eth_base;
	u16 m_eth_control;
};

class turquoise_ioga_device : public interpro_ioga_device
{
public:
	turquoise_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	virtual void map(address_map &map) override;

	void eth_w(offs_t offset, u16 data, u16 mem_mask = ~0);
	u16 eth_r(offs_t offset, u16 mem_mask = ~0);

protected:
	virtual TIMER_CALLBACK_MEMBER(eth_reset) override;

	enum eth_base_mask
	{
		ETH_BASE_MASK = 0xffe00000
	};
	u32 eth_base_r() { return m_eth_base; }
	void eth_base_w(offs_t offset, u32 data, u32 mem_mask = ~0);

	enum eth_control_mask
	{
		ETH_CA    = 0x0001, // channel attention
		ETH_FLUSH = 0x0002,
		ETH_BUF   = 0x0004,
		ETH_QUAD  = 0x0008,
		ETH_BERR  = 0x0010, // bus error
		ETH_PERR  = 0x0020, // parity error
		ETH_RESET = 0x0040,
		ETH_WTAG  = 0x0600,
		ETH_RTAG  = 0x3000,

		//ETH_MASK     = 0x4ff2  // channel attention and error bits not persistent
	};
	u16 eth_control_r() { return m_eth_control; }
	void eth_control_w(offs_t offset, u16 data, u16 mem_mask = ~0);

private:
	u32 m_eth_base;
	u16 m_eth_control;
};

class sapphire_ioga_device : public interpro_ioga_device
{
public:
	sapphire_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	virtual void map(address_map &map) override;

	virtual TIMER_CALLBACK_MEMBER(timer_60hz) override;

	void eth_w(offs_t offset, u16 data, u16 mem_mask = ~0);
	u16 eth_r(offs_t offset, u16 mem_mask = ~0);

	u32 timer2_count_r(offs_t offset, u32 mem_mask = ~0);
	void timer2_count_w(offs_t offset, u32 data, u32 mem_mask = ~0);
	u32 timer2_value_r(offs_t offset, u32 mem_mask = ~0);
	void timer2_value_w(offs_t offset, u32 data, u32 mem_mask = ~0);

	enum timer3_mask
	{
		TIMER3_COUNT   = 0x3fffffff,
		TIMER3_START   = 0x40000000,
		TIMER3_EXPIRED = 0x80000000
	};
	u32 timer3_r(offs_t offset, u32 mem_mask = ~0);
	void timer3_w(offs_t offset, u32 data, u32 mem_mask = ~0);


	u16 softint_vector_r(offs_t offset) { return m_swicr[offset]; }
	void softint_vector_w(offs_t offset, u16 data, u16 mem_mask = ~0);

	virtual IRQ_CALLBACK_MEMBER(acknowledge_interrupt) override;

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;

	virtual TIMER_CALLBACK_MEMBER(interrupt_check) override;
	virtual TIMER_CALLBACK_MEMBER(eth_reset) override;

	enum eth_remap_mask
	{
		ETH_CHA_FLUSH  = 0x00000008,
		ETH_CHA_BUF    = 0x00000010,
		ETH_CHA_QUAD   = 0x00000020,
		ETH_CHA_WTAG   = 0x000001c0,
		ETH_CHA_RTAG   = 0x00000e00,
		ETH_REMAP_ADDR = 0xfffff000
	};
	u32 eth_remap_r() { return m_eth_remap; }
	void eth_remap_w(u32 data);

	enum eth_mappg_mask
	{
		ETH_CHB_FLUSH = 0x00000008,
		ETH_CHB_BUF   = 0x00000010,
		ETH_CHB_QUAD  = 0x00000020,
		ETH_CHB_WTAG  = 0x000001c0,
		ETH_CHB_RTAG  = 0x00000e00,
		ETH_MAPPG     = 0xfffff000
	};
	u32 eth_mappg_r() { return m_eth_mappg; }
	void eth_mappg_w(u32 data);

	enum eth_control_mask
	{
		ETH_CA       = 0x00000001, // channel attention
		ETH_MAPEN    = 0x00000002,
		ETH_CHC_BUF  = 0x00000010,
		ETH_CHC_QUAD = 0x00000020,
		ETH_CHC_WTAG = 0x000001c0,
		ETH_CHC_RTAG = 0x00000e00,
		ETH_BERR     = 0x00001000,
		ETH_MMBE     = 0x00002000,
		ETH_RESET    = 0x00004000,

		ETH_MASK     = 0x00004ff2  // channel attention and error bits not persistent
	};
	u32 eth_control_r();
	void eth_control_w(offs_t offset, u32 data, u32 mem_mask = ~0);

	TIMER_CALLBACK_MEMBER(timer2) {}
	TIMER_CALLBACK_MEMBER(timer3);

	virtual u8 get_int_count() const override { return INTERRUPT_COUNT; }
	virtual u8 get_reg_offset(u8 const number) const override { return (number + 2) % INTERRUPT_COUNT; }
	virtual u8 get_int_number(u8 const offset) const override { return (offset + INTERRUPT_COUNT - 2) % INTERRUPT_COUNT; }

private:
	static const u8 INTERRUPT_COUNT = 19;

	u32 m_eth_remap;
	u32 m_eth_mappg;
	u32 m_eth_control;

	u32 m_timer2_count;
	u32 m_timer2_value;
	u32 m_timer3_count;

	emu_timer *m_timer2;
	emu_timer *m_timer3;

	u16 m_swicr[8];
};

// device type definition
DECLARE_DEVICE_TYPE(EMERALD_IOGA, emerald_ioga_device)
DECLARE_DEVICE_TYPE(TURQUOISE_IOGA, turquoise_ioga_device)
DECLARE_DEVICE_TYPE(SAPPHIRE_IOGA, sapphire_ioga_device)

#endif // MAME_MACHINE_INTERPRO_IOGA_H