// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/**********************************************************************
SGI IOC2 I/O Controller emulation
**********************************************************************/
#ifndef MAME_MACHINE_IOC2_H
#define MAME_MACHINE_IOC2_H
#pragma once
#include "cpu/mips/mips3.h"
#include "machine/8042kbdc.h"
#include "machine/pc_lpt.h"
#include "machine/pckeybrd.h"
#include "machine/pit8253.h"
#include "machine/z80scc.h"
#define MCFG_IOC2_GUINNESS_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, SGI_IOC2_GUINNESS, 0)
#define MCFG_IOC2_FULL_HOUSE_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, SGI_IOC2_FULL_HOUSE, 0)
#define MCFG_IOC2_CPU(cpu_tag) \
downcast<ioc2_device &>(*device).set_cpu_tag(cpu_tag);
class ioc2_device : public device_t
{
public:
void set_cpu_tag(const char *tag) { m_maincpu.set_tag(tag); }
DECLARE_WRITE32_MEMBER( write );
DECLARE_READ32_MEMBER( read );
DECLARE_INPUT_CHANGED_MEMBER( power_button );
DECLARE_INPUT_CHANGED_MEMBER( volume_down );
DECLARE_INPUT_CHANGED_MEMBER( volume_up );
void lower_local0_irq(uint8_t source_mask);
void raise_local0_irq(uint8_t source_mask);
void lower_local1_irq(uint8_t source_mask);
void raise_local1_irq(uint8_t source_mask);
enum
{
INT3_LOCAL0_FIFO = 0x01,
INT3_LOCAL0_SCSI0 = 0x02,
INT3_LOCAL0_SCSI1 = 0x04,
INT3_LOCAL0_ETHERNET = 0x08,
INT3_LOCAL0_MC_DMA = 0x10,
INT3_LOCAL0_PARALLEL = 0x20,
INT3_LOCAL0_GRAPHICS = 0x40,
INT3_LOCAL0_MAPPABLE0 = 0x80,
};
enum
{
INT3_LOCAL1_GP0 = 0x01,
INT3_LOCAL1_PANEL = 0x02,
INT3_LOCAL1_GP2 = 0x04,
INT3_LOCAL1_MAPPABLE1 = 0x08,
INT3_LOCAL1_HPC_DMA = 0x10,
INT3_LOCAL1_AC_FAIL = 0x20,
INT3_LOCAL1_VSYNC = 0x40,
INT3_LOCAL1_RETRACE = 0x80,
};
protected:
ioc2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
enum
{
PI1_DATA_REG = 0x00/4,
PI1_CTRL_REG = 0x04/4,
PI1_STATUS_REG = 0x08/4,
PI1_DMA_CTRL_REG = 0x0c/4,
PI1_INT_STATUS_REG = 0x10/4,
PI1_INT_MASK_REG = 0x14/4,
PI1_TIMER1_REG = 0x18/4,
PI1_TIMER2_REG = 0x1c/4,
PI1_TIMER3_REG = 0x20/4,
PI1_TIMER4_REG = 0x24/4,
SERIAL1_CMD_REG = 0x30/4,
SERIAL1_DATA_REG = 0x34/4,
SERIAL2_CMD_REG = 0x38/4,
SERIAL2_DATA_REG = 0x3c/4,
KBD_MOUSE_REGS1 = 0x40/4,
KBD_MOUSE_REGS2 = 0x44/4,
GENCTRL_SELECT_REG = 0x48/4,
GENCTRL_REG = 0x4c/4,
PANEL_REG = 0x50/4,
SYSID_REG = 0x58/4,
READ_REG = 0x60/4,
DMA_SEL_REG = 0x68/4,
RESET_REG = 0x70/4,
WRITE_REG = 0x78/4,
INT3_LOCAL0_STATUS_REG = 0x80/4,
INT3_LOCAL0_MASK_REG = 0x84/4,
INT3_LOCAL1_STATUS_REG = 0x88/4,
INT3_LOCAL1_MASK_REG = 0x8c/4,
INT3_MAP_STATUS_REG = 0x90/4,
INT3_MAP_MASK0_REG = 0x94/4,
INT3_MAP_MASK1_REG = 0x98/4,
INT3_MAP_POLARITY_REG = 0x9c/4,
INT3_TIMER_CLEAR_REG = 0xa0/4,
INT3_ERROR_STATUS_REG = 0xa4/4,
TIMER_COUNT0_REG = 0xb0/4,
TIMER_COUNT1_REG = 0xb4/4,
TIMER_COUNT2_REG = 0xb8/4,
TIMER_CONTROL_REG = 0xbc/4,
};
enum
{
FRONT_PANEL_POWER_STATE = 0x01,
FRONT_PANEL_POWER_BUTTON_INT = 0x02,
FRONT_PANEL_VOL_DOWN_INT = 0x10,
FRONT_PANEL_VOL_DOWN_HOLD = 0x20,
FRONT_PANEL_VOL_UP_INT = 0x40,
FRONT_PANEL_VOL_UP_HOLD = 0x80,
};
enum
{
DMA_SEL_CLOCK_SEL_MASK = 0x30,
DMA_SEL_CLOCK_SEL_10MHz = 0x00,
DMA_SEL_CLOCK_SEL_6_67MHz = 0x10,
DMA_SEL_CLOCK_SEL_EXT = 0x20,
};
required_device<mips3_device> m_maincpu;
required_device<scc85230_device> m_scc;
required_device<pc_lpt_device> m_pi1; // we assume standard parallel port (SPP) mode
// TODO: SGI parallel port (SGIPP), HP BOISE high speed parallel port (HPBPP), and Ricoh scanner modes
required_device<kbdc8042_device> m_kbdc;
required_device<pit8254_device> m_pit;
virtual void handle_reset_reg_write(uint8_t data);
virtual uint8_t get_system_id() = 0;
uint8_t m_gen_ctrl_select_reg;
uint8_t m_gen_ctrl_reg;
uint8_t m_front_panel_reg;
uint8_t m_read_reg;
uint8_t m_dma_sel;
uint8_t m_reset_reg;
uint8_t m_write_reg;
uint8_t m_int3_local0_status_reg;
uint8_t m_int3_local0_mask_reg;
uint8_t m_int3_local1_status_reg;
uint8_t m_int3_local1_mask_reg;
uint8_t m_int3_map_status_reg;
uint8_t m_int3_map_mask0_reg;
uint8_t m_int3_map_mask1_reg;
uint8_t m_int3_map_pol_reg;
uint8_t m_int3_timer_clear_reg;
uint8_t m_int3_err_status_reg;
uint32_t m_par_read_cnt;
uint32_t m_par_cntl;
uint8_t m_system_id;
static const char *SCC_TAG;
static const char *PI1_TAG;
static const char *KBDC_TAG;
static const char *PIT_TAG;
static const char *RS232A_TAG;
static const char *RS232B_TAG;
static const XTAL SCC_PCLK;
static const XTAL SCC_RXA_CLK;
static const XTAL SCC_TXA_CLK;
static const XTAL SCC_RXB_CLK;
static const XTAL SCC_TXB_CLK;
};
class ioc2_guinness_device : public ioc2_device
{
public:
ioc2_guinness_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
uint8_t get_system_id() override { return 0x01; }
};
class ioc2_full_house_device : public ioc2_device
{
public:
ioc2_full_house_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
uint8_t get_system_id() override { return 0x20; }
};
DECLARE_DEVICE_TYPE(SGI_IOC2_GUINNESS, ioc2_guinness_device)
DECLARE_DEVICE_TYPE(SGI_IOC2_FULL_HOUSE, ioc2_full_house_device)
#endif // MAME_MACHINE_IOC2_H