sgi: Various minor fixes and improvements, nw

This commit is contained in:
mooglyguy 2018-11-18 00:44:15 +01:00
parent fed9a5b345
commit 48c0c4a269
9 changed files with 1264 additions and 996 deletions

View File

@ -3020,6 +3020,8 @@ files {
MAME_DIR .. "src/mame/machine/sgi.h",
MAME_DIR .. "src/mame/machine/hal2.cpp",
MAME_DIR .. "src/mame/machine/hal2.h",
MAME_DIR .. "src/mame/machine/hpc1.cpp",
MAME_DIR .. "src/mame/machine/hpc1.h",
MAME_DIR .. "src/mame/machine/hpc3.cpp",
MAME_DIR .. "src/mame/machine/hpc3.h",
MAME_DIR .. "src/mame/machine/ioc2.cpp",

View File

@ -1,61 +1,40 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/*********************************************************************\
*
* SGI Indigo workstation
*
* Skeleton Driver
*
* Todo: Everything
*
* Memory map:
*
* 1fa00000 - 1fa02047 Memory Controller
* 1fb80000 - 1fb9a7ff HPC1 CHIP0
* 1fc00000 - 1fc7ffff BIOS
*
\*********************************************************************/
/*********************************************************************
SGI Indigo workstation
To-Do:
- IP12 (R3000):
* Everything
- IP20 (R4000):
* Figure out why the keyboard/mouse diagnostic fails
* Work out a proper RAM mapping, or why the installer bails due
to trying to access virtual address ffffa02c:
88002584: lw $sp,-$5fd4($0)
**********************************************************************/
#include "emu.h"
#include "bus/rs232/rs232.h"
#include "bus/rs232/hlemouse.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsicd512.h"
#include "bus/scsi/scsihd.h"
#include "bus/sgikbd/sgikbd.h"
//#include "cpu/dsp56k/dsp56k.h"
#include "cpu/mips/mips1.h"
#include "cpu/mips/mips3.h"
#include "machine/dp8573.h"
#include "machine/eepromser.h"
#include "machine/pit8253.h"
#include "machine/hpc1.h"
#include "machine/sgi.h"
#include "machine/wd33c93.h"
#include "machine/z80scc.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#define ENABLE_ENTRY_GFX (1)
#define LOG_UNKNOWN (1 << 0)
#define LOG_INT (1 << 1)
#define LOG_HPC (1 << 2)
#define LOG_EEPROM (1 << 4)
#define LOG_DMA (1 << 5)
#define LOG_SCSI (1 << 6)
#define LOG_SCSI_DMA (1 << 7)
#define LOG_DUART0 (1 << 8)
#define LOG_DUART1 (1 << 9)
#define LOG_DUART2 (1 << 10)
#define LOG_PIT (1 << 11)
#define LOG_DSP (1 << 12)
#define LOG_GFX (1 << 13)
#define LOG_GFX_CMD (1 << 14)
#define LOG_DUART (LOG_DUART0 | LOG_DUART1 | LOG_DUART2)
#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_HPC | LOG_EEPROM | LOG_DMA | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT | LOG_DSP | LOG_GFX | LOG_GFX_CMD)
#define LOG_DSP (1 << 2)
#define LOG_GFX (1 << 3)
#define LOG_GFX_CMD (1 << 4)
#define LOG_ALL (LOG_UNKNOWN | LOG_INT | LOG_DSP | LOG_GFX | LOG_GFX_CMD)
#define VERBOSE (LOG_ALL & ~(LOG_DUART0 | LOG_DUART1 | LOG_SCSI | LOG_SCSI_DMA | LOG_EEPROM | LOG_PIT | LOG_DSP))
#define VERBOSE (LOG_UNKNOWN)
#include "logmacro.h"
class indigo_state : public driver_device
@ -63,12 +42,9 @@ class indigo_state : public driver_device
public:
indigo_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_wd33c93(*this, "wd33c93")
, m_scc(*this, "scc%u", 0U)
, m_hpc(*this, "hpc")
, m_eeprom(*this, "eeprom")
, m_pit(*this, "pit")
, m_rtc(*this, "rtc")
, m_share1(*this, "share1")
, m_dsp_ram(*this, "dspram")
, m_palette(*this, "palette")
{
@ -80,59 +56,19 @@ protected:
virtual void machine_start() override;
virtual void machine_reset() override;
DECLARE_READ32_MEMBER(hpc_r);
DECLARE_WRITE32_MEMBER(hpc_w);
DECLARE_READ32_MEMBER(int_r);
DECLARE_WRITE32_MEMBER(int_w);
DECLARE_READ32_MEMBER(dsp_ram_r);
DECLARE_WRITE32_MEMBER(dsp_ram_w);
DECLARE_READ32_MEMBER(entry_r);
DECLARE_WRITE32_MEMBER(entry_w);
DECLARE_WRITE_LINE_MEMBER(scsi_irq);
void set_timer_int_clear(uint32_t data);
DECLARE_WRITE_LINE_MEMBER(timer0_int);
DECLARE_WRITE_LINE_MEMBER(timer1_int);
DECLARE_WRITE_LINE_MEMBER(timer2_int);
DECLARE_WRITE_LINE_MEMBER(duart0_int_w);
DECLARE_WRITE_LINE_MEMBER(duart1_int_w);
DECLARE_WRITE_LINE_MEMBER(duart2_int_w);
void duart_int_w(int channel, int status);
void raise_local_irq(int channel, uint8_t source_mask);
void lower_local_irq(int channel, uint8_t source_mask);
void update_irq(int channel);
void fetch_chain(address_space &space);
void advance_chain(address_space &space);
void scsi_dma();
void do_rex_command();
static void cdrom_config(device_t *device);
void indigo_map(address_map &map);
uint32_t screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect);
enum
{
LOCAL0_FIFO_GIO0 = 0x01,
LOCAL0_PARALLEL = 0x02,
LOCAL0_SCSI = 0x04,
LOCAL0_ETHERNET = 0x08,
LOCAL0_GFX_DMA = 0x10,
LOCAL0_DUART = 0x20,
LOCAL0_GIO1 = 0x40,
LOCAL0_VME0 = 0x80,
LOCAL1_GR1_CASE = 0x02,
LOCAL1_VME1 = 0x08,
LOCAL1_DSP = 0x10,
LOCAL1_ACFAIL = 0x20,
LOCAL1_VIDEO = 0x40,
LOCAL1_RETRACE_GIO2 = 0x80
};
enum
{
REX15_PAGE0_SET = 0x00000000,
@ -179,27 +115,6 @@ protected:
REX15_CONTROL = 0x06
};
struct hpc_t
{
uint8_t m_misc_status;
uint32_t m_cpu_aux_ctrl;
uint32_t m_parbuf_ptr;
uint32_t m_local_int_status[2];
uint32_t m_local_int_mask[2];
bool m_int_status[2];
uint32_t m_vme_intmask0;
uint32_t m_vme_intmask1;
uint32_t m_scsi0_dma_desc;
uint32_t m_scsi0_dma_ctrl;
uint32_t m_scsi0_dma_addr;
uint32_t m_scsi0_dma_flag;
uint32_t m_scsi0_dma_next;
uint16_t m_scsi0_dma_length;
bool m_scsi0_dma_to_mem;
bool m_scsi0_dma_active;
bool m_scsi0_dma_end;
};
struct lg1_t
{
uint32_t m_config_sel;
@ -223,56 +138,27 @@ protected:
uint8_t m_palette_idx;
uint8_t m_palette_channel;
uint8_t m_palette_entry[3];
bool m_waiting_for_palette_addr;
uint8_t m_pix_read_mask[256];
};
enum
{
HPC_DMACTRL_RESET = 0x01,
HPC_DMACTRL_FLUSH = 0x02,
HPC_DMACTRL_TO_MEM = 0x10,
HPC_DMACTRL_ENABLE = 0x80
};
required_device<cpu_device> m_maincpu;
required_device<wd33c93_device> m_wd33c93;
required_device_array<scc8530_device, 3> m_scc;
required_device<hpc1_device> m_hpc;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<pit8254_device> m_pit;
required_device<dp8573_device> m_rtc;
required_shared_ptr<uint32_t> m_share1;
required_shared_ptr<uint32_t> m_dsp_ram;
required_device<palette_device> m_palette;
hpc_t m_hpc;
address_space *m_space;
lg1_t m_lg1;
std::unique_ptr<uint8_t[]> m_framebuffer;
uint8_t m_duart_int_status;
static char const *const RS232A_TAG;
static char const *const 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;
};
/*static*/ char const *const indigo_state::RS232A_TAG = "rs232a";
/*static*/ char const *const indigo_state::RS232B_TAG = "rs232b";
/*static*/ const XTAL indigo_state::SCC_PCLK = 10_MHz_XTAL;
/*static*/ const XTAL indigo_state::SCC_RXA_CLK = 3.6864_MHz_XTAL; // Needs verification
/*static*/ const XTAL indigo_state::SCC_TXA_CLK = XTAL(0);
/*static*/ const XTAL indigo_state::SCC_RXB_CLK = 3.6864_MHz_XTAL; // Needs verification
/*static*/ const XTAL indigo_state::SCC_TXB_CLK = XTAL(0);
class indigo3k_state : public indigo_state
{
public:
indigo3k_state(const machine_config &mconfig, device_type type, const char *tag)
: indigo_state(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
{
}
@ -280,6 +166,8 @@ public:
protected:
void mem_map(address_map &map);
required_device<r3000a_device> m_maincpu;
};
class indigo4k_state : public indigo_state
@ -287,38 +175,28 @@ class indigo4k_state : public indigo_state
public:
indigo4k_state(const machine_config &mconfig, device_type type, const char *tag)
: indigo_state(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_mem_ctrl(*this, "memctrl")
{
}
void indigo4k(machine_config &config);
protected:
virtual void machine_reset() override;
void mem_map(address_map &map);
DECLARE_WRITE32_MEMBER(write_ram);
required_device<r4000be_device> m_maincpu;
required_device<sgi_mc_device> m_mem_ctrl;
};
void indigo_state::machine_start()
{
m_framebuffer = std::make_unique<uint8_t[]>(1024*768);
save_item(NAME(m_hpc.m_misc_status));
save_item(NAME(m_hpc.m_cpu_aux_ctrl));
save_item(NAME(m_hpc.m_parbuf_ptr));
save_item(NAME(m_hpc.m_local_int_status));
save_item(NAME(m_hpc.m_local_int_mask));
save_item(NAME(m_hpc.m_int_status));
save_item(NAME(m_hpc.m_vme_intmask0));
save_item(NAME(m_hpc.m_vme_intmask1));
save_item(NAME(m_hpc.m_scsi0_dma_desc));
save_item(NAME(m_hpc.m_scsi0_dma_ctrl));
save_item(NAME(m_hpc.m_scsi0_dma_addr));
save_item(NAME(m_hpc.m_scsi0_dma_flag));
save_item(NAME(m_hpc.m_scsi0_dma_next));
save_item(NAME(m_hpc.m_scsi0_dma_length));
save_item(NAME(m_hpc.m_scsi0_dma_to_mem));
save_item(NAME(m_hpc.m_scsi0_dma_active));
save_item(NAME(m_hpc.m_scsi0_dma_end));
save_item(NAME(m_lg1.m_config_sel));
save_item(NAME(m_lg1.m_write_addr));
save_item(NAME(m_lg1.m_control));
@ -338,538 +216,23 @@ void indigo_state::machine_start()
save_item(NAME(m_lg1.m_palette_idx));
save_item(NAME(m_lg1.m_palette_channel));
save_item(NAME(m_lg1.m_palette_entry));
save_item(NAME(m_lg1.m_waiting_for_palette_addr));
save_item(NAME(m_lg1.m_pix_read_mask));
save_item(NAME(m_duart_int_status));
save_pointer(NAME(&m_framebuffer[0]), 1024*768);
}
void indigo_state::machine_reset()
{
memset(&m_hpc, 0, sizeof(hpc_t));
memset(&m_lg1, 0, sizeof(lg1_t));
memset(&m_framebuffer[0], 0, 1024*768);
m_duart_int_status = 0;
}
READ32_MEMBER(indigo_state::hpc_r)
void indigo4k_state::machine_reset()
{
if (offset >= 0x0e00/4 && offset <= 0x0e7c/4)
return m_rtc->read(space, offset - 0xe00/4);
indigo_state::machine_reset();
switch (offset)
{
case 0x005c/4:
LOGMASKED(LOG_HPC | LOG_UNKNOWN, "%s: HPC Unknown Read: %08x & %08x\n",
machine().describe_context(), 0x1fb80000 + offset*4, mem_mask);
return 0;
case 0x0094/4:
LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_scsi0_dma_ctrl, mem_mask);
return m_hpc.m_scsi0_dma_ctrl;
case 0x00ac/4:
LOGMASKED(LOG_HPC, "%s: HPC Parallel Buffer Pointer Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_parbuf_ptr, mem_mask);
return m_hpc.m_parbuf_ptr;
case 0x00c0/4:
LOGMASKED(LOG_HPC, "%s: HPC Endianness Read: %08x & %08x\n", machine().describe_context(), 0x00000040, mem_mask);
return 0x00000040;
case 0x0120/4:
{
uint32_t ret = m_wd33c93->read(space, 0) << 8;
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 0 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
case 0x0124/4:
{
uint32_t ret = m_wd33c93->read(space, 1) << 8;
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 1 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
case 0x01b0/4:
LOGMASKED(LOG_HPC, "%s: HPC Misc. Status Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_misc_status, mem_mask);
return m_hpc.m_misc_status;
case 0x01bc/4:
{
uint32_t ret = (m_hpc.m_cpu_aux_ctrl & ~0x10) | m_eeprom->do_read() << 4;
LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
case 0x01c0/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Status Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_status[0], mem_mask);
return m_hpc.m_local_int_status[0];
case 0x01c4/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Mask Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_mask[0], mem_mask);
return m_hpc.m_local_int_mask[0];
case 0x01c8/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Status Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_status[1], mem_mask);
return m_hpc.m_local_int_status[1];
case 0x01cc/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Mask Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_local_int_mask[1], mem_mask);
return m_hpc.m_local_int_mask[1];
case 0x01d4/4:
LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 0 Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_vme_intmask0, mem_mask);
return m_hpc.m_vme_intmask0;
case 0x01d8/4:
LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 1 Read: %08x & %08x\n", machine().describe_context(), m_hpc.m_vme_intmask1, mem_mask);
return m_hpc.m_vme_intmask1;
case 0x01f0/4:
{
const uint8_t data = m_pit->read(0);
LOGMASKED(LOG_PIT, "%s: Read Timer Count0 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x01f4/4:
{
const uint8_t data = m_pit->read(1);
LOGMASKED(LOG_PIT, "%s: Read Timer Count1 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x01f8/4:
{
const uint8_t data = m_pit->read(2);
LOGMASKED(LOG_PIT, "%s: Read Timer Count2 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x01fc/4:
{
const uint8_t data = m_pit->read(3);
LOGMASKED(LOG_PIT, "%s: Read Timer Control Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x0d00/4:
case 0x0d10/4:
case 0x0d20/4:
{
const uint32_t index = (offset >> 2) & 3;
uint32_t ret = m_scc[index]->ba_cd_r(space, 3);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
case 0x0d04/4:
case 0x0d14/4:
case 0x0d24/4:
{
const uint32_t index = (offset >> 2) & 3;
const uint32_t ret = m_scc[index]->ba_cd_r(space, 2);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
case 0x0d08/4:
case 0x0d18/4:
case 0x0d28/4:
{
const uint32_t index = (offset >> 2) & 3;
const uint32_t ret = m_scc[index]->ba_cd_r(space, 1);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
case 0x0d0c/4:
case 0x0d1c/4:
case 0x0d2c/4:
{
const uint32_t index = (offset >> 2) & 3;
const uint32_t ret = m_scc[index]->ba_cd_r(space, 0);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
default:
LOGMASKED(LOG_HPC | LOG_UNKNOWN, "%s: Unknown HPC Read: %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, mem_mask);
return 0;
}
return 0;
}
void indigo_state::fetch_chain(address_space &space)
{
m_hpc.m_scsi0_dma_flag = space.read_dword(m_hpc.m_scsi0_dma_desc);
m_hpc.m_scsi0_dma_addr = space.read_dword(m_hpc.m_scsi0_dma_desc+4);
m_hpc.m_scsi0_dma_next = space.read_dword(m_hpc.m_scsi0_dma_desc+8);
m_hpc.m_scsi0_dma_length = m_hpc.m_scsi0_dma_flag & 0x1fff;
LOGMASKED(LOG_SCSI_DMA, "Fetched SCSI DMA Descriptor block:\n");
LOGMASKED(LOG_SCSI_DMA, " Ctrl: %08x\n", m_hpc.m_scsi0_dma_flag);
LOGMASKED(LOG_SCSI_DMA, " Addr: %08x\n", m_hpc.m_scsi0_dma_addr);
LOGMASKED(LOG_SCSI_DMA, " Next: %08x\n", m_hpc.m_scsi0_dma_next);
LOGMASKED(LOG_SCSI_DMA, " Length: %04x\n", m_hpc.m_scsi0_dma_length);
m_hpc.m_scsi0_dma_end = BIT(m_hpc.m_scsi0_dma_addr, 31);
m_hpc.m_scsi0_dma_addr &= 0x0fffffff;
m_hpc.m_scsi0_dma_next &= 0x0fffffff;
}
void indigo_state::advance_chain(address_space &space)
{
m_hpc.m_scsi0_dma_addr++;
m_hpc.m_scsi0_dma_length--;
if (m_hpc.m_scsi0_dma_length == 0)
{
if (m_hpc.m_scsi0_dma_end)
{
LOGMASKED(LOG_SCSI_DMA, "HPC: Disabling SCSI DMA due to end of chain\n");
m_hpc.m_scsi0_dma_active = false;
m_hpc.m_scsi0_dma_ctrl &= ~HPC_DMACTRL_ENABLE;
}
else
{
m_hpc.m_scsi0_dma_desc = m_hpc.m_scsi0_dma_next;
fetch_chain(space);
}
}
}
WRITE32_MEMBER(indigo_state::hpc_w)
{
if (offset >= 0x0e00/4 && offset <= 0x0e7c/4)
{
m_rtc->write(space, offset - 0xe00/4, (uint8_t)data);
return;
}
switch (offset)
{
case 0x0090/4:
LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Descriptor Pointer Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_hpc.m_scsi0_dma_desc = data;
fetch_chain(space);
break;
case 0x0094/4:
LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_hpc.m_scsi0_dma_ctrl = data &~ (HPC_DMACTRL_FLUSH | HPC_DMACTRL_RESET);
m_hpc.m_scsi0_dma_to_mem = (m_hpc.m_scsi0_dma_ctrl & HPC_DMACTRL_TO_MEM);
m_hpc.m_scsi0_dma_active = (m_hpc.m_scsi0_dma_ctrl & HPC_DMACTRL_ENABLE);
break;
case 0x00ac/4:
LOGMASKED(LOG_HPC, "%s: HPC Parallel Buffer Pointer Write: %08x (%08x)\n", machine().describe_context(), data, mem_mask);
m_hpc.m_parbuf_ptr = data;
break;
case 0x0120/4:
if (ACCESSING_BITS_8_15)
{
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_wd33c93->write(space, 0, (uint8_t)(data >> 8));
}
break;
case 0x0124/4:
if (ACCESSING_BITS_8_15)
{
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Data Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_wd33c93->write(space, 1, (uint8_t)(data >> 8));
}
break;
case 0x01b0/4:
LOGMASKED(LOG_HPC, "%s: HPC Misc. Status Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
if (BIT(data, 0))
LOGMASKED(LOG_HPC, " Force DSP hard reset\n" );
if (BIT(data, 1))
LOGMASKED(LOG_HPC, " Force IRQA\n" );
if (BIT(data, 2))
LOGMASKED(LOG_HPC, " Set IRQA polarity high\n" );
else
LOGMASKED(LOG_HPC, " Set IRQA polarity low\n" );
if (BIT(data, 3))
LOGMASKED(LOG_HPC, " SRAM size: 32K\n" );
else
LOGMASKED(LOG_HPC, " SRAM size: 8K\n" );
m_hpc.m_misc_status = data;
break;
case 0x01bc/4:
m_hpc.m_cpu_aux_ctrl = data;
LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Write: %08x & %08x\n", machine().describe_context(), data, mem_mask );
if (BIT(data, 0))
{
LOGMASKED(LOG_EEPROM, " CPU board LED on\n");
}
m_eeprom->di_write(BIT(data, 3));
m_eeprom->cs_write(BIT(data, 1));
m_eeprom->clk_write(BIT(data, 2));
break;
case 0x01c0/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x01c4/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 0 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_hpc.m_local_int_mask[0] = data;
break;
case 0x01c8/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x01cc/4:
LOGMASKED(LOG_HPC, "%s: HPC Local Interrupt 1 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_hpc.m_local_int_mask[1] = data;
break;
case 0x01d4/4:
LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_hpc.m_vme_intmask0 = data;
break;
case 0x01d8/4:
LOGMASKED(LOG_HPC, "%s: HPC VME Interrupt Mask 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_hpc.m_vme_intmask1 = data;
break;
case 0x01e0/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Interrupt Clear Register: %08x\n", machine().describe_context(), data);
set_timer_int_clear(data);
break;
case 0x01f0/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count0 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
if (ACCESSING_BITS_24_31)
m_pit->write(0, (uint8_t)(data >> 24));
else if (ACCESSING_BITS_0_7)
m_pit->write(0, (uint8_t)data);
return;
case 0x01f4/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count1 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pit->write(1, (uint8_t)data);
return;
case 0x01f8/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count2 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pit->write(2, (uint8_t)data);
return;
case 0x01fc/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pit->write(3, (uint8_t)data);
return;
case 0x0d00/4:
case 0x0d10/4:
case 0x0d20/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 3, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
case 0x0d04/4:
case 0x0d14/4:
case 0x0d24/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 2, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
case 0x0d08/4:
case 0x0d18/4:
case 0x0d28/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 1, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
case 0x0d0c/4:
case 0x0d1c/4:
case 0x0d2c/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 0, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
default:
LOGMASKED(LOG_HPC | LOG_UNKNOWN, "%s: Unknown HPC write: %08x = %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, data, mem_mask);
break;
}
}
void indigo_state::scsi_dma()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
int byte_count = m_wd33c93->get_dma_count();
LOGMASKED(LOG_SCSI_DMA, "HPC: Transferring %d bytes %s %08x %s SCSI0\n",
byte_count, m_hpc.m_scsi0_dma_to_mem ? "to" : "from", m_hpc.m_scsi0_dma_addr, m_hpc.m_scsi0_dma_to_mem ? "from" : "to");
uint8_t dma_buffer[512];
if (m_hpc.m_scsi0_dma_to_mem)
{
// HPC SCSI DMA: device to host
if (byte_count <= 512)
{
m_wd33c93->dma_read_data(byte_count, dma_buffer);
for (int i = 0; i < byte_count; i++)
{
LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr);
space.write_byte(m_hpc.m_scsi0_dma_addr, dma_buffer[i]);
advance_chain(space);
if (!m_hpc.m_scsi0_dma_active)
break;
}
}
else
{
while (byte_count)
{
int sub_count = m_wd33c93->dma_read_data(512, dma_buffer);
for (int i = 0; i < sub_count; i++)
{
LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr);
space.write_byte(m_hpc.m_scsi0_dma_addr, dma_buffer[i]);
advance_chain(space);
if (!m_hpc.m_scsi0_dma_active)
break;
}
byte_count -= sub_count;
if (!m_hpc.m_scsi0_dma_active)
break;
}
}
}
else
{
// HPC SCSI DMA: host to device
if (byte_count <= 512)
{
for (int i = 0; i < byte_count; i++)
{
dma_buffer[i] = space.read_byte(m_hpc.m_scsi0_dma_addr);
LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr);
advance_chain(space);
if (!m_hpc.m_scsi0_dma_active)
break;
}
m_wd33c93->dma_write_data(byte_count, dma_buffer);
}
else
{
while (byte_count)
{
int sub_count = std::min(512, byte_count);
for (int i = 0; i < sub_count; i++)
{
dma_buffer[i] = space.read_byte(m_hpc.m_scsi0_dma_addr);
LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_hpc.m_scsi0_dma_addr);
advance_chain(space);
if (!m_hpc.m_scsi0_dma_active)
break;
}
m_wd33c93->dma_write_data(sub_count, dma_buffer);
if (!m_hpc.m_scsi0_dma_active)
{
break;
}
else
{
byte_count -= sub_count;
}
}
}
}
// clear DMA on the controller
m_wd33c93->clear_dma();
}
WRITE_LINE_MEMBER(indigo_state::scsi_irq)
{
if (state)
{
LOGMASKED(LOG_SCSI, "SCSI: Set IRQ\n");
int count = m_wd33c93->get_dma_count();
LOGMASKED(LOG_SCSI_DMA, "SCSI: count %d, active %d\n", count, m_hpc.m_scsi0_dma_active);
if (count && m_hpc.m_scsi0_dma_active)
scsi_dma();
raise_local_irq(0, LOCAL0_SCSI);
}
else
{
LOGMASKED(LOG_SCSI, "SCSI: Clear IRQ\n");
lower_local_irq(0, LOCAL0_SCSI);
}
}
void indigo_state::set_timer_int_clear(uint32_t data)
{
if (BIT(data, 0))
{
LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 0 Interrupt: %d\n", data);
m_maincpu->set_input_line(MIPS3_IRQ2, CLEAR_LINE);
}
if (BIT(data, 1))
{
LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 1 Interrupt: %d\n", data);
m_maincpu->set_input_line(MIPS3_IRQ3, CLEAR_LINE);
}
}
WRITE_LINE_MEMBER(indigo_state::timer0_int)
{
LOGMASKED(LOG_PIT, "Timer0 Interrupt: %d\n", state);
if (state)
m_maincpu->set_input_line(MIPS3_IRQ2, ASSERT_LINE);
}
WRITE_LINE_MEMBER(indigo_state::timer1_int)
{
LOGMASKED(LOG_PIT, "Timer2 Interrupt: %d\n", state);
if (state)
m_maincpu->set_input_line(MIPS3_IRQ3, ASSERT_LINE);
}
WRITE_LINE_MEMBER(indigo_state::timer2_int)
{
LOGMASKED(LOG_PIT, "Timer2 Interrupt (Disabled): %d\n", state);
}
WRITE_LINE_MEMBER(indigo_state::duart0_int_w) { duart_int_w(0, state); }
WRITE_LINE_MEMBER(indigo_state::duart1_int_w) { duart_int_w(1, state); }
WRITE_LINE_MEMBER(indigo_state::duart2_int_w) { duart_int_w(2, state); }
void indigo_state::duart_int_w(int channel, int state)
{
m_duart_int_status &= ~(1 << channel);
m_duart_int_status |= state << channel;
if (m_duart_int_status)
{
LOGMASKED(LOG_DUART0 << channel, "Raising DUART Interrupt: %02x\n", m_duart_int_status);
raise_local_irq(0, LOCAL0_DUART);
}
else
{
LOGMASKED(LOG_DUART0 << channel, "Lowering DUART Interrupt\n");
lower_local_irq(0, LOCAL0_DUART);
}
}
void indigo_state::raise_local_irq(int channel, uint8_t source_mask)
{
m_hpc.m_local_int_status[channel] |= source_mask;
bool old_status = m_hpc.m_int_status[channel];
m_hpc.m_int_status[channel] = (m_hpc.m_local_int_status[channel] & m_hpc.m_local_int_mask[channel]);
if (old_status != m_hpc.m_int_status[channel])
update_irq(channel);
}
void indigo_state::lower_local_irq(int channel, uint8_t source_mask)
{
m_hpc.m_local_int_status[channel] &= ~source_mask;
bool old_status = m_hpc.m_int_status[channel];
m_hpc.m_int_status[channel] = (m_hpc.m_local_int_status[channel] & m_hpc.m_local_int_mask[channel]);
if (old_status != m_hpc.m_int_status[channel])
update_irq(channel);
}
void indigo_state::update_irq(int channel)
{
LOGMASKED(LOG_INT, "%s IRQ%d: %02x & %02x\n", channel, m_hpc.m_int_status[channel] ? "Asserting" : "Clearing",
m_hpc.m_local_int_status[channel], m_hpc.m_local_int_mask[channel]);
m_maincpu->set_input_line(MIPS3_IRQ0, m_hpc.m_int_status[channel] ? ASSERT_LINE : CLEAR_LINE);
// set up low RAM mirror
membank("bank1")->set_base(m_share1);
}
READ32_MEMBER(indigo_state::int_r)
@ -1150,12 +513,8 @@ uint32_t indigo_state::screen_update(screen_device &device, bitmap_rgb32 &bitmap
void indigo_state::indigo_map(address_map &map)
{
map(0x00000000, 0x0007ffff).ram().share("share1");
map(0x08000000, 0x0fffffff).ram().share("share2");
map(0x10000000, 0x13ffffff).ram().share("share3");
map(0x18000000, 0x1bffffff).ram().share("share4");
map(0x1f3f0000, 0x1f3fffff).rw(FUNC(indigo_state::entry_r), FUNC(indigo_state::entry_w));
map(0x1fb80000, 0x1fb8ffff).rw(FUNC(indigo_state::hpc_r), FUNC(indigo_state::hpc_w));
map(0x1fb80000, 0x1fb8ffff).rw(m_hpc, FUNC(hpc1_device::read), FUNC(hpc1_device::write));
map(0x1fbd9000, 0x1fbd903f).rw(FUNC(indigo_state::int_r), FUNC(indigo_state::int_w));
map(0x1fbe0000, 0x1fbfffff).rw(FUNC(indigo_state::dsp_ram_r), FUNC(indigo_state::dsp_ram_w)).share("dspram");
}
@ -1163,32 +522,41 @@ void indigo_state::indigo_map(address_map &map)
void indigo3k_state::mem_map(address_map &map)
{
indigo_map(map);
map(0x1fc00000, 0x1fc3ffff).rom().share("share5").region("user1", 0);
map(0x1fc00000, 0x1fc3ffff).rom().share("share10").region("user1", 0);
}
WRITE32_MEMBER(indigo4k_state::write_ram)
{
// if banks 2 or 3 are enabled, kill it, we only want 128MB
if (m_mem_ctrl->read(space, 0xc8/4, 0xffffffff) & 0x10001000)
{
// a random perturbation so the memory test fails
data ^= 0xffffffff;
}
// if banks 0 or 1 have 2 membanks, also kill it, we only want 128MB
if (m_mem_ctrl->read(space, 0xc0/4, 0xffffffff) & 0x40004000)
{
// a random perturbation so the memory test fails
data ^= 0xffffffff;
}
COMBINE_DATA(&m_share1[offset & 0x03ffffff]);
}
void indigo4k_state::mem_map(address_map &map)
{
indigo_map(map);
map(0x1fa00000, 0x1fa1ffff).rw("sgi_mc", FUNC(sgi_mc_device::read), FUNC(sgi_mc_device::write));
map(0x00000000, 0x0007ffff).bankrw("bank1");
map(0x08000000, 0x17ffffff).ram().share("share1").w(FUNC(indigo4k_state::write_ram)); /* 128 MB of main RAM */
map(0x1fa00000, 0x1fa1ffff).rw(m_mem_ctrl, FUNC(sgi_mc_device::read), FUNC(sgi_mc_device::write));
map(0x1fc00000, 0x1fc7ffff).rom().share("share5").region("user1", 0);
map(0x20000000, 0x27ffffff).ram().share("share1").w(FUNC(indigo4k_state::write_ram)); /* 128 MB of main RAM */
}
static INPUT_PORTS_START( indigo )
PORT_START("unused")
PORT_BIT ( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
static INPUT_PORTS_START(indigo)
INPUT_PORTS_END
void indigo_state::cdrom_config(device_t *device)
{
cdda_device *cdda = device->subdevice<cdda_device>("cdda");
cdda->add_route(ALL_OUTPUTS, ":mono", 1.0);
}
static void indigo_mice(device_slot_interface &device)
{
device.option_add("sgimouse", SGI_HLE_SERIAL_MOUSE);
}
void indigo_state::indigo_base(machine_config &config)
{
/* video hardware */
@ -1201,65 +569,7 @@ void indigo_state::indigo_base(machine_config &config)
PALETTE(config, m_palette, 256);
SPEAKER(config, "mono").front_center();
SCC8530N(config, m_scc[0], SCC_PCLK);
m_scc[0]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value());
m_scc[0]->out_int_callback().set(FUNC(indigo_state::duart0_int_w));
m_scc[0]->out_txda_callback().set("keyboard", FUNC(sgi_keyboard_port_device::write_txd));
SCC8530N(config, m_scc[1], SCC_PCLK);
m_scc[1]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value());
m_scc[1]->out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd));
m_scc[1]->out_dtra_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_dtr));
m_scc[1]->out_rtsa_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_rts));
m_scc[1]->out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd));
m_scc[1]->out_dtrb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_dtr));
m_scc[1]->out_rtsb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_rts));
m_scc[1]->out_int_callback().set(FUNC(indigo_state::duart1_int_w));
SCC8530N(config, m_scc[2], SCC_PCLK);
m_scc[2]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value());
m_scc[2]->out_int_callback().set(FUNC(indigo_state::duart2_int_w));
SGIKBD_PORT(config, "keyboard", default_sgi_keyboard_devices, "hlekbd").rxd_handler().set(m_scc[0], FUNC(z80scc_device::rxa_w));
rs232_port_device &mouseport(RS232_PORT(config, "mouseport", indigo_mice, "sgimouse"));
mouseport.set_fixed(true);
mouseport.rxd_handler().set(m_scc[0], FUNC(scc8530_device::rxa_w));
mouseport.cts_handler().set(m_scc[0], FUNC(scc8530_device::ctsa_w));
mouseport.dcd_handler().set(m_scc[0], FUNC(scc8530_device::dcda_w));
rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr));
rs232a.cts_handler().set(m_scc[1], FUNC(scc8530_device::ctsa_w));
rs232a.dcd_handler().set(m_scc[1], FUNC(scc8530_device::dcda_w));
rs232a.rxd_handler().set(m_scc[1], FUNC(scc8530_device::rxa_w));
rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr));
rs232b.cts_handler().set(m_scc[1], FUNC(scc8530_device::ctsb_w));
rs232b.dcd_handler().set(m_scc[1], FUNC(scc8530_device::dcdb_w));
rs232b.rxd_handler().set(m_scc[1], FUNC(scc8530_device::rxb_w));
scsi_port_device &scsi(SCSI_PORT(config, "scsi"));
scsi.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_1));
scsi.set_slot_device(2, "cdrom", RRD45, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4));
scsi.slot(2).set_option_machine_config("cdrom", cdrom_config);
DP8573(config, m_rtc);
WD33C93(config, m_wd33c93);
m_wd33c93->set_scsi_port("scsi");
m_wd33c93->irq_cb().set(FUNC(indigo_state::scsi_irq));
EEPROM_93C56_16BIT(config, m_eeprom);
PIT8254(config, m_pit, 0);
m_pit->set_clk<0>(1000000);
m_pit->set_clk<1>(1000000);
m_pit->set_clk<2>(1500000);
m_pit->out_handler<0>().set(FUNC(indigo_state::timer0_int));
m_pit->out_handler<1>().set(FUNC(indigo_state::timer1_int));
m_pit->out_handler<2>().set(FUNC(indigo_state::timer2_int));
}
void indigo3k_state::indigo3k(machine_config &config)
@ -1269,17 +579,21 @@ void indigo3k_state::indigo3k(machine_config &config)
R3000A(config, m_maincpu, 33.333_MHz_XTAL, 32768, 32768);
downcast<r3000a_device &>(*m_maincpu).set_endianness(ENDIANNESS_BIG);
m_maincpu->set_addrmap(AS_PROGRAM, &indigo3k_state::mem_map);
SGI_HPC1(config, m_hpc, m_maincpu, m_eeprom);
}
void indigo4k_state::indigo4k(machine_config &config)
{
indigo_base(config);
mips3_device &cpu(R4400BE(config, m_maincpu, 50000000*3));
mips3_device &cpu(R4000BE(config, m_maincpu, 50000000*2));
cpu.set_icache_size(32768);
cpu.set_dcache_size(32768);
cpu.set_addrmap(AS_PROGRAM, &indigo4k_state::mem_map);
SGI_MC(config, "sgi_mc");
SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom);
SGI_HPC1(config, m_hpc, m_maincpu, m_eeprom);
}
ROM_START( indigo3k )

View File

@ -67,6 +67,7 @@
#include "cpu/mips/mips3.h"
#include "machine/ds1386.h"
#include "machine/eepromser.h"
#include "machine/hal2.h"
#include "machine/hpc3.h"
#include "machine/ioc2.h"
@ -91,6 +92,7 @@ public:
, m_mainram(*this, "mainram")
, m_mem_ctrl(*this, "memctrl")
, m_scsi_ctrl(*this, "wd33c93")
, m_eeprom(*this, "eeprom")
, m_ldac(*this, "ldac")
, m_rdac(*this, "rdac")
, m_newport(*this, "newport")
@ -108,6 +110,8 @@ public:
protected:
virtual void machine_reset() override;
DECLARE_READ32_MEMBER(eeprom_r);
DECLARE_WRITE32_MEMBER(eeprom_w);
DECLARE_READ32_MEMBER(enet_r);
DECLARE_WRITE32_MEMBER(enet_w);
DECLARE_READ32_MEMBER(eisa_io_r);
@ -127,6 +131,7 @@ protected:
required_shared_ptr<uint32_t> m_mainram;
required_device<sgi_mc_device> m_mem_ctrl;
required_device<wd33c93_device> m_scsi_ctrl;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<dac_16bit_r2r_twos_complement_device> m_ldac;
required_device<dac_16bit_r2r_twos_complement_device> m_rdac;
required_device<newport_video_device> m_newport;
@ -135,7 +140,7 @@ protected:
required_device<ioc2_device> m_ioc2;
required_device<ds1386_device> m_rtc;
inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ... );
uint32_t m_cpu_aux_ctrl;
};
/*static*/ char const *const ip22_state::HAL2_TAG = "hal2";
@ -160,19 +165,21 @@ private:
required_device<wd33c93_device> m_scsi_ctrl2;
};
#define VERBOSE_LEVEL ( 0 )
inline void ATTR_PRINTF(3,4) ip22_state::verboselog(int n_level, const char *s_fmt, ... )
READ32_MEMBER(ip22_state::eeprom_r)
{
if( VERBOSE_LEVEL >= n_level )
{
va_list v;
char buf[ 32768 ];
va_start( v, s_fmt );
vsprintf( buf, s_fmt, v );
va_end( v );
logerror("%08x: %s", m_maincpu->pc(), buf);
}
// Disabled - we don't have a dump from real hardware, and IRIX 5.x freaks out with default contents.
uint32_t ret = (m_cpu_aux_ctrl & ~0x10);// | m_eeprom->do_read() << 4;
logerror("%s: HPC Serial EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
WRITE32_MEMBER(ip22_state::eeprom_w)
{
m_cpu_aux_ctrl = data;
logerror("%s: HPC Serial EEPROM Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_eeprom->di_write(BIT(data, 3));
m_eeprom->cs_write(BIT(data, 1));
m_eeprom->clk_write(BIT(data, 2));
}
READ32_MEMBER(ip22_state::enet_r)
@ -232,7 +239,7 @@ void ip22_state::ip22_map(address_map &map)
map(0x1fb80000, 0x1fb8ffff).rw(m_hpc3, FUNC(hpc3_device::pbusdma_r), FUNC(hpc3_device::pbusdma_w));
map(0x1fb90000, 0x1fb9ffff).rw(m_hpc3, FUNC(hpc3_device::hd_enet_r), FUNC(hpc3_device::hd_enet_w));
map(0x1fbb0000, 0x1fbb0003).ram(); /* unknown, but read a lot and discarded */
map(0x1fbb0008, 0x1fbb000b).rw(FUNC(ip22_state::eeprom_r), FUNC(ip22_state::eeprom_w));
map(0x1fbc0000, 0x1fbc7fff).rw(m_hpc3, FUNC(hpc3_device::hd_r<0>), FUNC(hpc3_device::hd_w<0>));
map(0x1fbd4000, 0x1fbd44ff).rw(FUNC(ip22_state::enet_r), FUNC(ip22_state::enet_w));
map(0x1fbd8000, 0x1fbd83ff).rw(m_hal2, FUNC(hal2_device::read), FUNC(hal2_device::write));
@ -291,7 +298,7 @@ void ip22_state::ip22_base(machine_config &config)
NEWPORT_VIDEO(config, m_newport, m_maincpu, m_ioc2);
SGI_MC(config, m_mem_ctrl);
SGI_MC(config, m_mem_ctrl, m_maincpu, m_eeprom);
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@ -323,6 +330,8 @@ void ip22_state::ip22_base(machine_config &config)
SGI_IOC2_GUINNESS(config, m_ioc2, m_maincpu);
DS1386_8K(config, m_rtc, 32768);
EEPROM_93C56_16BIT(config, m_eeprom);
}
void ip22_state::ip225015(machine_config &config)

View File

@ -41,6 +41,7 @@ protected:
void o2_state::mem_map(address_map &map)
{
map(0x00000000, 0x00000fff).ram();
map(0x1fc00000, 0x1fc7ffff).rom().region("user1", 0);
}

725
src/mame/machine/hpc1.cpp Normal file
View File

@ -0,0 +1,725 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/**********************************************************************
SGI HPC1 "High-performance Peripheral Controller" emulation
**********************************************************************/
#include "emu.h"
#include "cpu/mips/mips3.h"
#include "bus/rs232/rs232.h"
#include "bus/rs232/hlemouse.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsicd512.h"
#include "bus/scsi/scsihd.h"
#include "bus/sgikbd/sgikbd.h"
#include "machine/hpc1.h"
#include "speaker.h"
#define LOG_UNKNOWN (1 << 0)
#define LOG_READS (1 << 1)
#define LOG_WRITES (1 << 2)
#define LOG_INT (1 << 3)
#define LOG_EEPROM (1 << 4)
#define LOG_SCSI (1 << 5)
#define LOG_SCSI_DMA (1 << 6)
#define LOG_DUART0 (1 << 7)
#define LOG_DUART1 (1 << 8)
#define LOG_DUART2 (1 << 9)
#define LOG_PIT (1 << 10)
#define LOG_REGS (LOG_UNKNOWN | LOG_READS | LOG_WRITES)
#define LOG_DUART (LOG_DUART0 | LOG_DUART1 | LOG_DUART2)
#define LOG_ALL (LOG_REGS | LOG_INT | LOG_EEPROM | LOG_SCSI | LOG_SCSI_DMA | LOG_DUART | LOG_PIT)
#define VERBOSE (LOG_UNKNOWN)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(SGI_HPC1, hpc1_device, "hpc1", "SGI HPC1")
/*static*/ char const *const hpc1_device::RS232A_TAG = "rs232a";
/*static*/ char const *const hpc1_device::RS232B_TAG = "rs232b";
/*static*/ const XTAL hpc1_device::SCC_PCLK = 10_MHz_XTAL;
/*static*/ const XTAL hpc1_device::SCC_RXA_CLK = 3.6864_MHz_XTAL; // Needs verification
/*static*/ const XTAL hpc1_device::SCC_TXA_CLK = XTAL(0);
/*static*/ const XTAL hpc1_device::SCC_RXB_CLK = 3.6864_MHz_XTAL; // Needs verification
/*static*/ const XTAL hpc1_device::SCC_TXB_CLK = XTAL(0);
hpc1_device::hpc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SGI_HPC1, tag, owner, clock)
, m_maincpu(*this, finder_base::DUMMY_TAG)
, m_eeprom(*this, finder_base::DUMMY_TAG)
, m_wd33c93(*this, "wd33c93")
, m_scc(*this, "scc%u", 0U)
, m_pit(*this, "pit")
, m_rtc(*this, "rtc")
{
}
void hpc1_device::device_start()
{
save_item(NAME(m_misc_status));
save_item(NAME(m_cpu_aux_ctrl));
save_item(NAME(m_parbuf_ptr));
save_item(NAME(m_local_int_status));
save_item(NAME(m_local_int_mask));
save_item(NAME(m_int_status));
save_item(NAME(m_vme_int_mask));
save_item(NAME(m_scsi_dma.m_desc));
save_item(NAME(m_scsi_dma.m_ctrl));
save_item(NAME(m_scsi_dma.m_addr));
save_item(NAME(m_scsi_dma.m_flag));
save_item(NAME(m_scsi_dma.m_next));
save_item(NAME(m_scsi_dma.m_length));
save_item(NAME(m_scsi_dma.m_to_mem));
save_item(NAME(m_scsi_dma.m_active));
save_item(NAME(m_scsi_dma.m_end));
save_item(NAME(m_duart_int_status));
}
void hpc1_device::device_reset()
{
m_misc_status = 0;
m_cpu_aux_ctrl = 0;
m_parbuf_ptr = 0;
memset(m_local_int_status, 0, sizeof(uint32_t) * 2);
memset(m_local_int_mask, 0, sizeof(uint32_t) * 2);
memset(m_int_status, 0, sizeof(bool) * 2);
memset(m_vme_int_mask, 0, sizeof(uint32_t) * 2);
m_scsi_dma.m_desc = 0;
m_scsi_dma.m_ctrl = 0;
m_scsi_dma.m_addr = 0;
m_scsi_dma.m_flag = 0;
m_scsi_dma.m_next = 0;
m_scsi_dma.m_length = 0;
m_scsi_dma.m_to_mem = false;
m_scsi_dma.m_active = false;
m_scsi_dma.m_end = false;
m_duart_int_status = 0;
m_cpu_space = &m_maincpu->space(AS_PROGRAM);
}
//**************************************************************************
// DEVICE HARDWARE
//**************************************************************************
void hpc1_device::cdrom_config(device_t *device)
{
cdda_device *cdda = device->subdevice<cdda_device>("cdda");
cdda->add_route(ALL_OUTPUTS, "^^mono", 1.0);
}
void hpc1_device::indigo_mice(device_slot_interface &device)
{
device.option_add("sgimouse", SGI_HLE_SERIAL_MOUSE);
}
void hpc1_device::device_add_mconfig(machine_config &config)
{
SCC85C30(config, m_scc[0], SCC_PCLK);
m_scc[0]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value());
m_scc[0]->out_int_callback().set(FUNC(hpc1_device::duart0_int_w));
m_scc[0]->out_txda_callback().set("keyboard", FUNC(sgi_keyboard_port_device::write_txd));
SCC85C30(config, m_scc[1], SCC_PCLK);
m_scc[1]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value());
m_scc[1]->out_txda_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_txd));
m_scc[1]->out_dtra_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_dtr));
m_scc[1]->out_rtsa_callback().set(RS232A_TAG, FUNC(rs232_port_device::write_rts));
m_scc[1]->out_txdb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_txd));
m_scc[1]->out_dtrb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_dtr));
m_scc[1]->out_rtsb_callback().set(RS232B_TAG, FUNC(rs232_port_device::write_rts));
m_scc[1]->out_int_callback().set(FUNC(hpc1_device::duart1_int_w));
SCC85C30(config, m_scc[2], SCC_PCLK);
m_scc[2]->configure_channels(SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value());
m_scc[2]->out_int_callback().set(FUNC(hpc1_device::duart2_int_w));
SGIKBD_PORT(config, "keyboard", default_sgi_keyboard_devices, "hlekbd").rxd_handler().set(m_scc[0], FUNC(z80scc_device::rxa_w));
rs232_port_device &mouseport(RS232_PORT(config, "mouseport", indigo_mice, "sgimouse"));
mouseport.set_fixed(true);
mouseport.rxd_handler().set(m_scc[0], FUNC(scc85c30_device::rxb_w));
mouseport.cts_handler().set(m_scc[0], FUNC(scc85c30_device::ctsb_w));
mouseport.dcd_handler().set(m_scc[0], FUNC(scc85c30_device::dcdb_w));
rs232_port_device &rs232a(RS232_PORT(config, RS232A_TAG, default_rs232_devices, nullptr));
rs232a.cts_handler().set(m_scc[1], FUNC(scc85c30_device::ctsa_w));
rs232a.dcd_handler().set(m_scc[1], FUNC(scc85c30_device::dcda_w));
rs232a.rxd_handler().set(m_scc[1], FUNC(scc85c30_device::rxa_w));
rs232_port_device &rs232b(RS232_PORT(config, RS232B_TAG, default_rs232_devices, nullptr));
rs232b.cts_handler().set(m_scc[1], FUNC(scc85c30_device::ctsb_w));
rs232b.dcd_handler().set(m_scc[1], FUNC(scc85c30_device::dcdb_w));
rs232b.rxd_handler().set(m_scc[1], FUNC(scc85c30_device::rxb_w));
scsi_port_device &scsi(SCSI_PORT(config, "scsi"));
scsi.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_1));
scsi.set_slot_device(2, "cdrom", RRD45, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_4));
scsi.slot(2).set_option_machine_config("cdrom", cdrom_config);
DP8573(config, m_rtc);
WD33C93(config, m_wd33c93);
m_wd33c93->set_scsi_port("scsi");
m_wd33c93->irq_cb().set(FUNC(hpc1_device::scsi_irq));
PIT8254(config, m_pit, 0);
m_pit->set_clk<0>(1000000);
m_pit->set_clk<1>(1000000);
m_pit->set_clk<2>(1000000);
m_pit->out_handler<0>().set(FUNC(hpc1_device::timer0_int));
m_pit->out_handler<1>().set(FUNC(hpc1_device::timer1_int));
m_pit->out_handler<2>().set(FUNC(hpc1_device::timer2_int));
SPEAKER(config, "mono").front_center();
}
//**************************************************************************
// REGISTER ACCESS
//**************************************************************************
READ32_MEMBER(hpc1_device::read)
{
if (offset >= 0x0e00/4 && offset <= 0x0e7c/4)
return m_rtc->read(space, offset - 0xe00/4);
switch (offset)
{
case 0x005c/4:
LOGMASKED(LOG_UNKNOWN, "%s: HPC Unknown Read: %08x & %08x\n",
machine().describe_context(), 0x1fb80000 + offset*4, mem_mask);
return 0;
case 0x0094/4:
LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Read: %08x & %08x\n", machine().describe_context(), m_scsi_dma.m_ctrl, mem_mask);
return m_scsi_dma.m_ctrl;
case 0x00ac/4:
LOGMASKED(LOG_READS, "%s: HPC Parallel Buffer Pointer Read: %08x & %08x\n", machine().describe_context(), m_parbuf_ptr, mem_mask);
return m_parbuf_ptr;
case 0x00c0/4:
LOGMASKED(LOG_READS, "%s: HPC Endianness Read: %08x & %08x\n", machine().describe_context(), 0x00000000, mem_mask);
return 0x00000000;
case 0x0120/4:
{
uint32_t ret = m_wd33c93->read(space, 0) << 8;
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 0 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
case 0x0124/4:
{
uint32_t ret = m_wd33c93->read(space, 1) << 8;
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Offset 1 Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
case 0x01b0/4:
LOGMASKED(LOG_READS, "%s: HPC Misc. Status Read: %08x & %08x\n", machine().describe_context(), m_misc_status, mem_mask);
return m_misc_status;
case 0x01bc/4:
{
uint32_t ret = (m_cpu_aux_ctrl & ~0x10) | m_eeprom->do_read() << 4;
LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
case 0x01c0/4:
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Status Read: %08x & %08x\n", machine().describe_context(), m_local_int_status[0], mem_mask);
return m_local_int_status[0];
case 0x01c4/4:
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Mask Read: %08x & %08x\n", machine().describe_context(), m_local_int_mask[0], mem_mask);
return m_local_int_mask[0];
case 0x01c8/4:
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Status Read: %08x & %08x\n", machine().describe_context(), m_local_int_status[1], mem_mask);
return m_local_int_status[1];
case 0x01cc/4:
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Mask Read: %08x & %08x\n", machine().describe_context(), m_local_int_mask[1], mem_mask);
return m_local_int_mask[1];
case 0x01d4/4:
LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 0 Read: %08x & %08x\n", machine().describe_context(), m_vme_int_mask[0], mem_mask);
return m_vme_int_mask[0];
case 0x01d8/4:
LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 1 Read: %08x & %08x\n", machine().describe_context(), m_vme_int_mask[1], mem_mask);
return m_vme_int_mask[1];
case 0x01f0/4:
{
const uint8_t data = m_pit->read(0);
LOGMASKED(LOG_PIT, "%s: Read Timer Count0 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x01f4/4:
{
const uint8_t data = m_pit->read(1);
LOGMASKED(LOG_PIT, "%s: Read Timer Count1 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x01f8/4:
{
const uint8_t data = m_pit->read(2);
LOGMASKED(LOG_PIT, "%s: Read Timer Count2 Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x01fc/4:
{
const uint8_t data = m_pit->read(3);
LOGMASKED(LOG_PIT, "%s: Read Timer Control Register: %02x & %08x\n", machine().describe_context(), data, mem_mask);
return data;
}
case 0x0d00/4:
case 0x0d10/4:
case 0x0d20/4:
{
const uint32_t index = (offset >> 2) & 3;
uint32_t ret = m_scc[index]->ba_cd_r(space, 3);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
case 0x0d04/4:
case 0x0d14/4:
case 0x0d24/4:
{
const uint32_t index = (offset >> 2) & 3;
const uint32_t ret = m_scc[index]->ba_cd_r(space, 2);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
case 0x0d08/4:
case 0x0d18/4:
case 0x0d28/4:
{
const uint32_t index = (offset >> 2) & 3;
const uint32_t ret = m_scc[index]->ba_cd_r(space, 1);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
case 0x0d0c/4:
case 0x0d1c/4:
case 0x0d2c/4:
{
const uint32_t index = (offset >> 2) & 3;
const uint32_t ret = m_scc[index]->ba_cd_r(space, 0);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Read: %08x & %08x\n", machine().describe_context(), index, ret, mem_mask);
return ret;
}
default:
LOGMASKED(LOG_UNKNOWN, "%s: Unknown HPC Read: %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, mem_mask);
return 0;
}
return 0;
}
WRITE32_MEMBER(hpc1_device::write)
{
if (offset >= 0x0e00/4 && offset <= 0x0e7c/4)
{
m_rtc->write(space, offset - 0xe00/4, (uint8_t)data);
return;
}
switch (offset)
{
case 0x0090/4:
LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Descriptor Pointer Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_scsi_dma.m_desc = data;
fetch_chain();
break;
case 0x0094/4:
LOGMASKED(LOG_SCSI_DMA, "%s: HPC SCSI DMA Control Register Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_scsi_dma.m_ctrl = data &~ (HPC_DMACTRL_FLUSH | HPC_DMACTRL_RESET);
m_scsi_dma.m_to_mem = (m_scsi_dma.m_ctrl & HPC_DMACTRL_TO_MEM);
m_scsi_dma.m_active = (m_scsi_dma.m_ctrl & HPC_DMACTRL_ENABLE);
break;
case 0x00ac/4:
LOGMASKED(LOG_WRITES, "%s: HPC Parallel Buffer Pointer Write: %08x (%08x)\n", machine().describe_context(), data, mem_mask);
m_parbuf_ptr = data;
break;
case 0x0120/4:
if (ACCESSING_BITS_8_15)
{
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_wd33c93->write(space, 0, (uint8_t)(data >> 8));
}
break;
case 0x0124/4:
if (ACCESSING_BITS_8_15)
{
LOGMASKED(LOG_SCSI, "%s: HPC SCSI Controller Data Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_wd33c93->write(space, 1, (uint8_t)(data >> 8));
}
break;
case 0x01b0/4:
LOGMASKED(LOG_WRITES, "%s: HPC Misc. Status Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
if (BIT(data, 0))
LOGMASKED(LOG_WRITES, " Force DSP hard reset\n" );
if (BIT(data, 1))
LOGMASKED(LOG_WRITES, " Force IRQA\n" );
if (BIT(data, 2))
LOGMASKED(LOG_WRITES, " Set IRQA polarity high\n" );
else
LOGMASKED(LOG_WRITES, " Set IRQA polarity low\n" );
if (BIT(data, 3))
LOGMASKED(LOG_WRITES, " SRAM size: 32K\n" );
else
LOGMASKED(LOG_WRITES, " SRAM size: 8K\n" );
m_misc_status = data;
break;
case 0x01bc/4:
m_cpu_aux_ctrl = data;
LOGMASKED(LOG_EEPROM, "%s: HPC Serial EEPROM Write: %08x & %08x\n", machine().describe_context(), data, mem_mask );
if (BIT(data, 0))
{
LOGMASKED(LOG_EEPROM, " CPU board LED on\n");
}
m_eeprom->di_write(BIT(data, 3));
m_eeprom->cs_write(BIT(data, 1));
m_eeprom->clk_write(BIT(data, 2));
break;
case 0x01c0/4:
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x01c4/4:
{
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 0 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
const uint32_t old_mask = m_local_int_mask[0];
m_local_int_mask[0] = data;
if (old_mask != m_local_int_mask[0])
update_irq(0);
break;
}
case 0x01c8/4:
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Status Write (Ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask);
break;
case 0x01cc/4:
{
LOGMASKED(LOG_INT, "%s: HPC Local Interrupt 1 Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
const uint32_t old_mask = m_local_int_mask[1];
m_local_int_mask[1] = data;
if (old_mask != m_local_int_mask[1])
update_irq(1);
break;
}
case 0x01d4/4:
LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_vme_int_mask[0] = data;
break;
case 0x01d8/4:
LOGMASKED(LOG_INT, "%s: HPC VME Interrupt Mask 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_vme_int_mask[1] = data;
break;
case 0x01e0/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Interrupt Clear Register: %08x\n", machine().describe_context(), data);
set_timer_int_clear(data);
break;
case 0x01f0/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count0 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
if (ACCESSING_BITS_24_31)
m_pit->write(0, (uint8_t)(data >> 24));
else if (ACCESSING_BITS_0_7)
m_pit->write(0, (uint8_t)data);
return;
case 0x01f4/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count1 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pit->write(1, (uint8_t)data);
return;
case 0x01f8/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Count2 Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pit->write(2, (uint8_t)data);
return;
case 0x01fc/4:
LOGMASKED(LOG_PIT, "%s: HPC Write Timer Control Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_pit->write(3, (uint8_t)data);
return;
case 0x0d00/4:
case 0x0d10/4:
case 0x0d20/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 3, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
case 0x0d04/4:
case 0x0d14/4:
case 0x0d24/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 2, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel B Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
case 0x0d08/4:
case 0x0d18/4:
case 0x0d28/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 1, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Control Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
case 0x0d0c/4:
case 0x0d1c/4:
case 0x0d2c/4:
{
const uint32_t index = (offset >> 2) & 3;
m_scc[index]->ba_cd_w(space, 0, (uint8_t)data);
LOGMASKED(LOG_DUART0 << index, "%s: HPC DUART%d Channel A Data Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
break;
}
default:
LOGMASKED(LOG_UNKNOWN, "%s: Unknown HPC write: %08x = %08x & %08x\n", machine().describe_context(), 0x1fb80000 + offset*4, data, mem_mask);
break;
}
}
//**************************************************************************
// SCSI DMA
//**************************************************************************
void hpc1_device::fetch_chain()
{
m_scsi_dma.m_flag = m_cpu_space->read_dword(m_scsi_dma.m_desc);
m_scsi_dma.m_addr = m_cpu_space->read_dword(m_scsi_dma.m_desc+4);
m_scsi_dma.m_next = m_cpu_space->read_dword(m_scsi_dma.m_desc+8);
m_scsi_dma.m_length = m_scsi_dma.m_flag & 0x1fff;
LOGMASKED(LOG_SCSI_DMA, "Fetched SCSI DMA Descriptor block:\n");
LOGMASKED(LOG_SCSI_DMA, " Ctrl: %08x\n", m_scsi_dma.m_flag);
LOGMASKED(LOG_SCSI_DMA, " Addr: %08x\n", m_scsi_dma.m_addr);
LOGMASKED(LOG_SCSI_DMA, " Next: %08x\n", m_scsi_dma.m_next);
LOGMASKED(LOG_SCSI_DMA, " Length: %04x\n", m_scsi_dma.m_length);
m_scsi_dma.m_end = BIT(m_scsi_dma.m_addr, 31);
m_scsi_dma.m_addr &= 0x0fffffff;
m_scsi_dma.m_next &= 0x0fffffff;
}
void hpc1_device::advance_chain()
{
m_scsi_dma.m_addr++;
m_scsi_dma.m_length--;
if (m_scsi_dma.m_length == 0)
{
if (m_scsi_dma.m_end)
{
LOGMASKED(LOG_SCSI_DMA, "HPC: Disabling SCSI DMA due to end of chain\n");
m_scsi_dma.m_active = false;
m_scsi_dma.m_ctrl &= ~HPC_DMACTRL_ENABLE;
}
else
{
m_scsi_dma.m_desc = m_scsi_dma.m_next;
fetch_chain();
}
}
}
void hpc1_device::scsi_dma()
{
int byte_count = m_wd33c93->get_dma_count();
LOGMASKED(LOG_SCSI_DMA, "HPC: Transferring %d bytes %s %08x %s SCSI0\n",
byte_count, m_scsi_dma.m_to_mem ? "to" : "from", m_scsi_dma.m_addr, m_scsi_dma.m_to_mem ? "from" : "to");
uint8_t dma_buffer[512];
if (m_scsi_dma.m_to_mem)
{
// HPC SCSI DMA: device to host
if (byte_count <= 512)
{
m_wd33c93->dma_read_data(byte_count, dma_buffer);
for (int i = 0; i < byte_count; i++)
{
LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_scsi_dma.m_addr);
m_cpu_space->write_byte(m_scsi_dma.m_addr, dma_buffer[i]);
advance_chain();
if (!m_scsi_dma.m_active)
break;
}
}
else
{
while (byte_count)
{
int sub_count = m_wd33c93->dma_read_data(512, dma_buffer);
for (int i = 0; i < sub_count; i++)
{
LOGMASKED(LOG_SCSI_DMA, "HPC: Reading %02x to %08x\n", dma_buffer[i], m_scsi_dma.m_addr);
m_cpu_space->write_byte(m_scsi_dma.m_addr, dma_buffer[i]);
advance_chain();
if (!m_scsi_dma.m_active)
break;
}
byte_count -= sub_count;
if (!m_scsi_dma.m_active)
break;
}
}
}
else
{
// HPC SCSI DMA: host to device
if (byte_count <= 512)
{
for (int i = 0; i < byte_count; i++)
{
dma_buffer[i] = m_cpu_space->read_byte(m_scsi_dma.m_addr);
LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_scsi_dma.m_addr);
advance_chain();
if (!m_scsi_dma.m_active)
break;
}
m_wd33c93->dma_write_data(byte_count, dma_buffer);
}
else
{
while (byte_count)
{
int sub_count = std::min(512, byte_count);
for (int i = 0; i < sub_count; i++)
{
dma_buffer[i] = m_cpu_space->read_byte(m_scsi_dma.m_addr);
LOGMASKED(LOG_SCSI_DMA, "HPC: Writing %02x from %08x\n", dma_buffer[i], m_scsi_dma.m_addr);
advance_chain();
if (!m_scsi_dma.m_active)
break;
}
m_wd33c93->dma_write_data(sub_count, dma_buffer);
if (!m_scsi_dma.m_active)
{
break;
}
else
{
byte_count -= sub_count;
}
}
}
}
// clear DMA on the controller
m_wd33c93->clear_dma();
}
//**************************************************************************
// PIT TIMERS
//**************************************************************************
void hpc1_device::set_timer_int_clear(uint32_t data)
{
if (BIT(data, 0))
{
LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 0 Interrupt: %d\n", data);
m_maincpu->set_input_line(MIPS3_IRQ2, CLEAR_LINE);
}
if (BIT(data, 1))
{
LOGMASKED(LOG_PIT | LOG_INT, "Clearing Timer 1 Interrupt: %d\n", data);
m_maincpu->set_input_line(MIPS3_IRQ3, CLEAR_LINE);
}
}
WRITE_LINE_MEMBER(hpc1_device::timer0_int)
{
LOGMASKED(LOG_PIT, "Timer0 Interrupt: %d\n", state);
if (state)
m_maincpu->set_input_line(MIPS3_IRQ2, ASSERT_LINE);
}
WRITE_LINE_MEMBER(hpc1_device::timer1_int)
{
LOGMASKED(LOG_PIT, "Timer2 Interrupt: %d\n", state);
if (state)
m_maincpu->set_input_line(MIPS3_IRQ3, ASSERT_LINE);
}
WRITE_LINE_MEMBER(hpc1_device::timer2_int)
{
LOGMASKED(LOG_PIT, "Timer2 Interrupt (Disabled): %d\n", state);
}
//**************************************************************************
// SERIAL DUARTS
//**************************************************************************
WRITE_LINE_MEMBER(hpc1_device::duart0_int_w) { duart_int_w(0, state); }
WRITE_LINE_MEMBER(hpc1_device::duart1_int_w) { duart_int_w(1, state); }
WRITE_LINE_MEMBER(hpc1_device::duart2_int_w) { duart_int_w(2, state); }
void hpc1_device::duart_int_w(int channel, int state)
{
m_duart_int_status &= ~(1 << channel);
m_duart_int_status |= state << channel;
if (m_duart_int_status)
{
LOGMASKED(LOG_DUART0 << channel, "Raising DUART Interrupt: %02x\n", m_duart_int_status);
raise_local_irq(0, LOCAL0_DUART);
}
else
{
LOGMASKED(LOG_DUART0 << channel, "Lowering DUART Interrupt\n");
lower_local_irq(0, LOCAL0_DUART);
}
}
//**************************************************************************
// INTERRUPTS
//**************************************************************************
void hpc1_device::raise_local_irq(int channel, uint8_t source_mask)
{
m_local_int_status[channel] |= source_mask;
update_irq(channel);
}
void hpc1_device::lower_local_irq(int channel, uint8_t source_mask)
{
m_local_int_status[channel] &= ~source_mask;
update_irq(channel);
}
void hpc1_device::update_irq(int channel)
{
bool old_status = m_int_status[channel];
m_int_status[channel] = (m_local_int_status[channel] & m_local_int_mask[channel]);
if (old_status != m_int_status[channel])
{
LOGMASKED(LOG_INT, "%s IRQ%d: %02x & %02x\n", m_int_status[channel] ? "Asserting" : "Clearing", channel,
m_local_int_status[channel], m_local_int_mask[channel]);
m_maincpu->set_input_line(MIPS3_IRQ0 + channel, m_int_status[channel] ? ASSERT_LINE : CLEAR_LINE);
}
}
WRITE_LINE_MEMBER(hpc1_device::scsi_irq)
{
if (state)
{
LOGMASKED(LOG_SCSI, "SCSI: Set IRQ\n");
int count = m_wd33c93->get_dma_count();
LOGMASKED(LOG_SCSI_DMA, "SCSI: count %d, active %d\n", count, m_scsi_dma.m_active);
if (count && m_scsi_dma.m_active)
scsi_dma();
raise_local_irq(0, LOCAL0_SCSI);
}
else
{
LOGMASKED(LOG_SCSI, "SCSI: Clear IRQ\n");
lower_local_irq(0, LOCAL0_SCSI);
}
}

136
src/mame/machine/hpc1.h Normal file
View File

@ -0,0 +1,136 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/**********************************************************************
SGI HPC1 "High-performance Peripheral Controller" emulation
**********************************************************************/
#ifndef MAME_MACHINE_HPC1_H
#define MAME_MACHINE_HPC1_H
#pragma once
#include "machine/dp8573.h"
#include "machine/eepromser.h"
#include "machine/pit8253.h"
#include "machine/wd33c93.h"
#include "machine/z80scc.h"
class hpc1_device : public device_t
{
public:
template <typename T, typename U>
hpc1_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&eeprom_tag)
: hpc1_device(mconfig, tag, owner, (uint32_t)0)
{
m_maincpu.set_tag(std::forward<T>(cpu_tag));
m_eeprom.set_tag(std::forward<U>(eeprom_tag));
}
hpc1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ32_MEMBER(read);
DECLARE_WRITE32_MEMBER(write);
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
DECLARE_WRITE_LINE_MEMBER(scsi_irq);
void set_timer_int_clear(uint32_t data);
DECLARE_WRITE_LINE_MEMBER(timer0_int);
DECLARE_WRITE_LINE_MEMBER(timer1_int);
DECLARE_WRITE_LINE_MEMBER(timer2_int);
DECLARE_WRITE_LINE_MEMBER(duart0_int_w);
DECLARE_WRITE_LINE_MEMBER(duart1_int_w);
DECLARE_WRITE_LINE_MEMBER(duart2_int_w);
void duart_int_w(int channel, int status);
void raise_local_irq(int channel, uint8_t source_mask);
void lower_local_irq(int channel, uint8_t source_mask);
void update_irq(int channel);
void fetch_chain();
void advance_chain();
void scsi_dma();
required_device<cpu_device> m_maincpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<wd33c93_device> m_wd33c93;
required_device_array<scc85c30_device, 3> m_scc;
required_device<pit8254_device> m_pit;
required_device<dp8573_device> m_rtc;
enum
{
LOCAL0_FIFO_GIO0 = 0x01,
LOCAL0_PARALLEL = 0x02,
LOCAL0_SCSI = 0x04,
LOCAL0_ETHERNET = 0x08,
LOCAL0_GFX_DMA = 0x10,
LOCAL0_DUART = 0x20,
LOCAL0_GIO1 = 0x40,
LOCAL0_VME0 = 0x80,
LOCAL1_GR1_CASE = 0x02,
LOCAL1_VME1 = 0x08,
LOCAL1_DSP = 0x10,
LOCAL1_ACFAIL = 0x20,
LOCAL1_VIDEO = 0x40,
LOCAL1_RETRACE_GIO2 = 0x80
};
enum
{
HPC_DMACTRL_RESET = 0x01,
HPC_DMACTRL_FLUSH = 0x02,
HPC_DMACTRL_TO_MEM = 0x10,
HPC_DMACTRL_ENABLE = 0x80
};
struct scsi_dma_t
{
uint32_t m_desc;
uint32_t m_ctrl;
uint32_t m_addr;
uint32_t m_flag;
uint32_t m_next;
uint16_t m_length;
bool m_to_mem;
bool m_active;
bool m_end;
};
static void cdrom_config(device_t *device);
static void indigo_mice(device_slot_interface &device);
uint8_t m_misc_status;
uint32_t m_cpu_aux_ctrl;
uint32_t m_parbuf_ptr;
uint32_t m_local_int_status[2];
uint32_t m_local_int_mask[2];
bool m_int_status[2];
uint32_t m_vme_int_mask[2];
scsi_dma_t m_scsi_dma;
uint8_t m_duart_int_status;
address_space *m_cpu_space;
static char const *const RS232A_TAG;
static char const *const 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;
};
DECLARE_DEVICE_TYPE(SGI_HPC1, hpc1_device)
#endif // MAME_MACHINE_HPC1_H

View File

@ -151,10 +151,8 @@ protected:
uint32_t m_pio_config[10];
address_space *m_cpu_space;
inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ... );
};
DECLARE_DEVICE_TYPE(SGI_HPC3, hpc3_device)
#endif // MAME_MACHINE_HAL2_H
#endif // MAME_MACHINE_HPC3_H

View File

@ -10,67 +10,69 @@
#include "emu.h"
#include "sgi.h"
#include "cpu/mips/mips3.h"
#define LOG_READS (1 << 0)
#define LOG_WRITES (1 << 1)
#define LOG_RPSS (1 << 2)
#define LOG_WATCHDOG (1 << 3)
#define LOG_MEMCFG (1 << 4)
#define LOG_UNKNOWN (1 << 5)
#define LOG_UNKNOWN (1 << 0)
#define LOG_READS (1 << 1)
#define LOG_WRITES (1 << 2)
#define LOG_RPSS (1 << 3)
#define LOG_WATCHDOG (1 << 4)
#define LOG_MEMCFG (1 << 5)
#define LOG_MEMCFG_EXT (1 << 6)
#define LOG_EEPROM (1 << 7)
#define LOG_DEFAULT (LOG_READS | LOG_WRITES | LOG_RPSS | LOG_WATCHDOG | LOG_UNKNOWN)
#define VERBOSE (0)
#define VERBOSE (LOG_UNKNOWN)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(SGI_MC, sgi_mc_device, "sgi_mc", "SGI Memory Controller")
sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SGI_MC, tag, owner, clock),
m_rpss_timer(nullptr),
m_cpu_control0(0),
m_cpu_control1(0),
m_watchdog(0),
m_sys_id(0),
m_rpss_divider(0),
m_refcnt_preload(0),
m_refcnt(0),
m_gio64_arb_param(0),
m_arb_cpu_time(0),
m_arb_burst_time(0),
m_mem_config0(0),
m_mem_config1(0),
m_cpu_mem_access_config(0),
m_gio_mem_access_config(0),
m_cpu_error_addr(0),
m_cpu_error_status(0),
m_gio_error_addr(0),
m_gio_error_status(0),
m_sys_semaphore(0),
m_gio_lock(0),
m_eisa_lock(0),
m_gio64_translate_mask(0),
m_gio64_substitute_bits(0),
m_dma_int_cause(0),
m_dma_control(0),
m_dma_tlb_entry0_hi(0),
m_dma_tlb_entry0_lo(0),
m_dma_tlb_entry1_hi(0),
m_dma_tlb_entry1_lo(0),
m_dma_tlb_entry2_hi(0),
m_dma_tlb_entry2_lo(0),
m_dma_tlb_entry3_hi(0),
m_dma_tlb_entry3_lo(0),
m_rpss_counter(0),
m_dma_mem_addr(0),
m_dma_size(0),
m_dma_stride(0),
m_dma_gio64_addr(0),
m_dma_mode(0),
m_dma_count(0),
m_dma_running(0),
m_rpss_divide_counter(0),
m_rpss_divide_count(0),
m_rpss_increment(0)
: device_t(mconfig, SGI_MC, tag, owner, clock)
, m_maincpu(*this, finder_base::DUMMY_TAG)
, m_eeprom(*this, finder_base::DUMMY_TAG)
, m_rpss_timer(nullptr)
, m_watchdog(0)
, m_sys_id(0)
, m_rpss_divider(0)
, m_refcnt_preload(0)
, m_refcnt(0)
, m_gio64_arb_param(0)
, m_arb_cpu_time(0)
, m_arb_burst_time(0)
, m_cpu_mem_access_config(0)
, m_gio_mem_access_config(0)
, m_cpu_error_addr(0)
, m_cpu_error_status(0)
, m_gio_error_addr(0)
, m_gio_error_status(0)
, m_sys_semaphore(0)
, m_gio_lock(0)
, m_eisa_lock(0)
, m_gio64_translate_mask(0)
, m_gio64_substitute_bits(0)
, m_dma_int_cause(0)
, m_dma_control(0)
, m_dma_tlb_entry0_hi(0)
, m_dma_tlb_entry0_lo(0)
, m_dma_tlb_entry1_hi(0)
, m_dma_tlb_entry1_lo(0)
, m_dma_tlb_entry2_hi(0)
, m_dma_tlb_entry2_lo(0)
, m_dma_tlb_entry3_hi(0)
, m_dma_tlb_entry3_lo(0)
, m_rpss_counter(0)
, m_dma_mem_addr(0)
, m_dma_size(0)
, m_dma_stride(0)
, m_dma_gio64_addr(0)
, m_dma_mode(0)
, m_dma_count(0)
, m_dma_running(0)
, m_eeprom_ctrl(0)
, m_rpss_divide_counter(0)
, m_rpss_divide_count(0)
, m_rpss_increment(0)
{
}
@ -83,18 +85,17 @@ void sgi_mc_device::device_start()
// if Indigo2, ID appropriately
if (!strcmp(machine().system().name, "ip244415"))
{
m_sys_id = 0x11; // rev. B MC, EISA bus present
m_sys_id = 0x12; // rev. C MC, EISA bus present
}
else
{
m_sys_id = 0x01; // rev. B MC, no EISA bus
m_sys_id = 0x02; // rev. C MC, no EISA bus
}
m_rpss_timer = timer_alloc(TIMER_RPSS);
m_rpss_timer->adjust(attotime::never);
save_item(NAME(m_cpu_control0));
save_item(NAME(m_cpu_control1));
save_item(NAME(m_cpu_control));
save_item(NAME(m_watchdog));
save_item(NAME(m_sys_id));
save_item(NAME(m_rpss_divider));
@ -103,8 +104,7 @@ void sgi_mc_device::device_start()
save_item(NAME(m_gio64_arb_param));
save_item(NAME(m_arb_cpu_time));
save_item(NAME(m_arb_burst_time));
save_item(NAME(m_mem_config0));
save_item(NAME(m_mem_config1));
save_item(NAME(m_mem_config));
save_item(NAME(m_cpu_mem_access_config));
save_item(NAME(m_gio_mem_access_config));
save_item(NAME(m_cpu_error_addr));
@ -134,6 +134,7 @@ void sgi_mc_device::device_start()
save_item(NAME(m_dma_mode));
save_item(NAME(m_dma_count));
save_item(NAME(m_dma_running));
save_item(NAME(m_eeprom_ctrl));
save_item(NAME(m_semaphore));
save_item(NAME(m_rpss_divide_counter));
save_item(NAME(m_rpss_divide_count));
@ -142,148 +143,203 @@ void sgi_mc_device::device_start()
void sgi_mc_device::device_reset()
{
m_cpu_control[0] = 0;
m_cpu_control[1] = 0;
m_watchdog = 0;
m_rpss_divider = 0x0104;
m_refcnt_preload = 0;
m_refcnt = 0;
m_gio64_arb_param = 0;
m_arb_cpu_time = 0;
m_arb_burst_time = 0;
m_mem_config[0] = 0;
m_mem_config[1] = 0;
m_cpu_mem_access_config = 0;
m_gio_mem_access_config = 0;
m_cpu_error_addr = 0;
m_cpu_error_status = 0;
m_gio_error_addr = 0;
m_gio_error_status = 0;
m_sys_semaphore = 0;
m_gio_lock = 0;
m_eisa_lock = 0;
m_gio64_translate_mask = 0;
m_gio64_substitute_bits = 0;
m_dma_int_cause = 0;
m_dma_control = 0;
m_dma_tlb_entry0_hi = 0;
m_dma_tlb_entry0_lo = 0;
m_dma_tlb_entry1_hi = 0;
m_dma_tlb_entry1_lo = 0;
m_dma_tlb_entry2_hi = 0;
m_dma_tlb_entry2_lo = 0;
m_dma_tlb_entry3_hi = 0;
m_dma_tlb_entry3_lo = 0;
m_rpss_counter = 0;
m_dma_mem_addr = 0;
m_dma_size = 0;
m_dma_stride = 0;
m_dma_gio64_addr = 0;
m_dma_mode = 0;
m_dma_count = 0;
m_dma_running = 0;
m_eeprom_ctrl = 0;
memset(m_semaphore, 0, sizeof(uint32_t) * 16);
m_rpss_timer->adjust(attotime::from_hz(10000000), 0, attotime::from_hz(10000000));
m_rpss_divider = 0x0104;
m_rpss_divide_counter = 4;
m_rpss_divide_count = 4;
m_rpss_increment = 1;
}
void sgi_mc_device::set_cpu_buserr(uint32_t address)
{
m_cpu_error_addr = address;
m_cpu_error_status = 0x00000400;
if (address & 1)
m_cpu_error_status |= 0x000000f0;
else
m_cpu_error_status |= 0x0000000f;
}
READ32_MEMBER(sgi_mc_device::read)
{
offset <<= 2;
switch (offset & ~4)
switch (offset & ~1)
{
case 0x0000:
LOGMASKED(LOG_READS, "%s: CPU Control 0 Read: %08x & %08x\n", machine().describe_context(), m_cpu_control0, mem_mask);
return m_cpu_control0;
case 0x0008:
LOGMASKED(LOG_READS, "%s: CPU Control 1 Read: %08x & %08x\n", machine().describe_context(), m_cpu_control1, mem_mask);
return m_cpu_control1;
case 0x0010:
case 0x0000/4:
case 0x0008/4:
{
const uint32_t index = (offset >> 3) & 1;
LOGMASKED(LOG_READS, "%s: CPU Control %d Read: %08x & %08x\n", machine().describe_context(), index, m_cpu_control[index], mem_mask);
return m_cpu_control[index];
}
case 0x0010/4:
LOGMASKED(LOG_WATCHDOG, "%s: Watchdog Timer Read: %08x & %08x\n", machine().describe_context(), m_watchdog, mem_mask);
return m_watchdog;
case 0x0018:
case 0x0018/4:
LOGMASKED(LOG_READS, "%s: System ID Read: %08x & %08x\n", machine().describe_context(), m_sys_id, mem_mask);
return m_sys_id;
case 0x0028:
case 0x0028/4:
LOGMASKED(LOG_RPSS, "%s: RPSS Divider Read: %08x & %08x\n", machine().describe_context(), m_rpss_divider, mem_mask);
return m_rpss_divider;
case 0x0030:
LOGMASKED(LOG_READS, "%s: R4000 EEPROM Read\n", machine().describe_context());
return 0;
case 0x0040:
case 0x0030/4:
{
// Disabled - we don't have a dump from real hardware, and IRIX 5.x freaks out with default contents.
uint32_t ret = (m_eeprom_ctrl & ~0x10);// | m_eeprom->do_read() << 4;
LOGMASKED(LOG_READS, "%s: R4000 EEPROM Read: %08x & %08x\n", machine().describe_context(), ret, mem_mask);
return ret;
}
case 0x0040/4:
LOGMASKED(LOG_READS, "%s: Refresh Count Preload Read: %08x & %08x\n", machine().describe_context(), m_refcnt_preload, mem_mask);
return m_refcnt_preload;
case 0x0048:
case 0x0048/4:
LOGMASKED(LOG_READS, "%s: Refresh Count Read: %08x & %08x\n", machine().describe_context(), m_refcnt, mem_mask);
return m_refcnt;
case 0x0080:
case 0x0080/4:
LOGMASKED(LOG_READS, "%s: GIO64 Arbitration Param Read: %08x & %08x\n", machine().describe_context(), m_gio64_arb_param, mem_mask);
return m_gio64_arb_param;
case 0x0088:
case 0x0088/4:
LOGMASKED(LOG_READS, "%s: Arbiter CPU Time Read: %08x & %08x\n", machine().describe_context(), m_arb_cpu_time, mem_mask);
return m_arb_cpu_time;
case 0x0098:
case 0x0098/4:
LOGMASKED(LOG_READS, "%s: Arbiter Long Burst Time Read: %08x & %08x\n", machine().describe_context(), m_arb_burst_time, mem_mask);
return m_arb_burst_time;
case 0x00c0:
LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 0 Read: %08x & %08x\n", machine().describe_context(), m_mem_config0, mem_mask);
return m_mem_config0;
case 0x00c8:
LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 1 Read: %08x & %08x\n", machine().describe_context(), m_mem_config1, mem_mask);
return m_mem_config1;
case 0x00d0:
case 0x00c0/4:
case 0x00c8/4:
{
const uint32_t index = (offset >> 1) & 1;
LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register %d Read: %08x & %08x\n", machine().describe_context(), index, m_mem_config[index], mem_mask);
return m_mem_config[index];
}
case 0x00d0/4:
LOGMASKED(LOG_READS, "%s: CPU Memory Access Config Params Read: %08x & %08x\n", machine().describe_context(), m_cpu_mem_access_config, mem_mask);
return m_cpu_mem_access_config;
case 0x00d8:
case 0x00d8/4:
LOGMASKED(LOG_READS, "%s: GIO Memory Access Config Params Read: %08x & %08x\n", machine().describe_context(), m_gio_mem_access_config, mem_mask);
return m_gio_mem_access_config;
case 0x00e0:
case 0x00e0/4:
LOGMASKED(LOG_READS, "%s: CPU Error Address Read: %08x & %08x\n", machine().describe_context(), m_cpu_error_addr, mem_mask);
return m_cpu_error_addr;
case 0x00e8:
case 0x00e8/4:
LOGMASKED(LOG_READS, "%s: CPU Error Status Read: %08x & %08x\n", machine().describe_context(), m_cpu_error_status, mem_mask);
return m_cpu_error_status;
case 0x00f0:
case 0x00f0/4:
LOGMASKED(LOG_READS, "%s: GIO Error Address Read: %08x & %08x\n", machine().describe_context(), m_gio_error_addr, mem_mask);
return m_gio_error_addr;
case 0x00f8:
case 0x00f8/4:
LOGMASKED(LOG_READS, "%s: GIO Error Status Read: %08x & %08x\n", machine().describe_context(), m_gio_error_status, mem_mask);
return m_gio_error_status;
case 0x0100:
case 0x0100/4:
LOGMASKED(LOG_READS, "%s: System Semaphore Read: %08x & %08x\n", machine().describe_context(), m_sys_semaphore, mem_mask);
return m_sys_semaphore;
case 0x0108:
case 0x0108/4:
LOGMASKED(LOG_READS, "%s: GIO Lock Read: %08x & %08x\n", machine().describe_context(), m_gio_lock, mem_mask);
return m_gio_lock;
case 0x0110:
case 0x0110/4:
LOGMASKED(LOG_READS, "%s: EISA Lock Read: %08x & %08x\n", machine().describe_context(), m_eisa_lock, mem_mask);
return m_eisa_lock;
case 0x0150:
case 0x0150/4:
LOGMASKED(LOG_READS, "%s: GIO64 Translation Address Mask Read: %08x & %08x\n", machine().describe_context(), m_gio64_translate_mask, mem_mask);
return m_gio64_translate_mask;
case 0x0158:
case 0x0158/4:
LOGMASKED(LOG_READS, "%s: GIO64 Translation Address Substitution Bits Read: %08x & %08x\n", machine().describe_context(), m_gio64_substitute_bits, mem_mask);
return m_gio64_substitute_bits;
case 0x0160:
case 0x0160/4:
LOGMASKED(LOG_READS, "%s: DMA Interrupt Cause: %08x & %08x\n", machine().describe_context(), m_dma_int_cause, mem_mask);
return m_dma_int_cause;
case 0x0168:
case 0x0168/4:
LOGMASKED(LOG_READS, "%s: DMA Control Read: %08x & %08x\n", machine().describe_context(), m_dma_control, mem_mask);
return m_dma_control;
case 0x0180:
case 0x0180/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 0 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry0_hi, mem_mask);
return m_dma_tlb_entry0_hi;
case 0x0188:
case 0x0188/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 0 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry0_lo, mem_mask);
return m_dma_tlb_entry0_lo;
case 0x0190:
case 0x0190/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 1 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry1_hi, mem_mask);
return m_dma_tlb_entry1_hi;
case 0x0198:
case 0x0198/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 1 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry1_lo, mem_mask);
return m_dma_tlb_entry1_lo;
case 0x01a0:
case 0x01a0/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 2 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry2_hi, mem_mask);
return m_dma_tlb_entry2_hi;
case 0x01a8:
case 0x01a8/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 2 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry2_lo, mem_mask);
return m_dma_tlb_entry2_lo;
case 0x01b0:
case 0x01b0/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 3 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry3_hi, mem_mask);
return m_dma_tlb_entry3_hi;
case 0x01b8:
case 0x01b8/4:
LOGMASKED(LOG_READS, "%s: DMA TLB Entry 3 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry3_lo, mem_mask);
return m_dma_tlb_entry3_lo;
case 0x1000:
case 0x1000/4:
LOGMASKED(LOG_RPSS, "%s: RPSS 100ns Counter Read: %08x & %08x\n", machine().describe_context(), m_rpss_counter, mem_mask);
return m_rpss_counter;
case 0x2000:
case 0x2008:
case 0x2000/4:
case 0x2008/4:
LOGMASKED(LOG_READS, "%s: DMA Memory Address Read: %08x & %08x\n", machine().describe_context(), m_dma_mem_addr, mem_mask);
return m_dma_mem_addr;
case 0x2010:
case 0x2010/4:
LOGMASKED(LOG_READS, "%s: DMA Line Count and Width Read: %08x & %08x\n", machine().describe_context(), m_dma_size, mem_mask);
return m_dma_size;
case 0x2018:
case 0x2018/4:
LOGMASKED(LOG_READS, "%s: DMA Line Zoom and Stride Read: %08x & %08x\n", machine().describe_context(), m_dma_stride, mem_mask);
return m_dma_stride;
case 0x2020:
case 0x2028:
case 0x2020/4:
case 0x2028/4:
LOGMASKED(LOG_READS, "%s: DMA GIO64 Address Read: %08x & %08x\n", machine().describe_context(), m_dma_gio64_addr, mem_mask);
return m_dma_gio64_addr;
case 0x2030:
case 0x2030/4:
LOGMASKED(LOG_READS, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), m_dma_mode, mem_mask);
return m_dma_mode;
case 0x2038:
case 0x2038/4:
LOGMASKED(LOG_READS, "%s: DMA Zoom Count Read: %08x & %08x\n", machine().describe_context(), m_dma_count, mem_mask);
return m_dma_count;
case 0x2040:
case 0x2040/4:
LOGMASKED(LOG_READS, "%s: DMA Start Read\n", machine().describe_context());
return 0;
case 0x2048:
case 0x2048/4:
LOGMASKED(LOG_READS, "%s: VDMA Running Read: %08x & %08x\n", machine().describe_context(), m_dma_running, mem_mask);
if (m_dma_running == 1)
{
@ -294,30 +350,31 @@ READ32_MEMBER(sgi_mc_device::read)
{
return 0;
}
case 0x10000:
case 0x11000:
case 0x12000:
case 0x13000:
case 0x14000:
case 0x15000:
case 0x16000:
case 0x17000:
case 0x18000:
case 0x19000:
case 0x1a000:
case 0x1b000:
case 0x1c000:
case 0x1d000:
case 0x1e000:
case 0x1f000:
case 0x10000/4:
case 0x11000/4:
case 0x12000/4:
case 0x13000/4:
case 0x14000/4:
case 0x15000/4:
case 0x16000/4:
case 0x17000/4:
case 0x18000/4:
case 0x19000/4:
case 0x1a000/4:
case 0x1b000/4:
case 0x1c000/4:
case 0x1d000/4:
case 0x1e000/4:
case 0x1f000/4:
{
const uint32_t data = m_semaphore[(offset - 0x10000) >> 12];
LOGMASKED(LOG_READS, "%s: Semaphore %d Read: %08x & %08x\n", machine().describe_context(), (offset - 0x10000) >> 12, data, mem_mask);
m_semaphore[(offset - 0x10000) >> 12] = 1;
const uint32_t index = (offset - 0x4000) >> 10;
const uint32_t data = m_semaphore[index];
LOGMASKED(LOG_READS, "%s: Semaphore %d Read: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
m_semaphore[index] = 1;
return data;
}
default:
LOGMASKED(LOG_READS | LOG_UNKNOWN, "%s: Unmapped MC read: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset, mem_mask);
LOGMASKED(LOG_READS | LOG_UNKNOWN, "%s: Unmapped MC read: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset*4, mem_mask);
return 0;
}
return 0;
@ -325,198 +382,219 @@ READ32_MEMBER(sgi_mc_device::read)
WRITE32_MEMBER( sgi_mc_device::write )
{
offset <<= 2;
switch (offset & ~4)
switch (offset & ~1)
{
case 0x0000:
LOGMASKED(LOG_WRITES, "%s: CPU Control 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_cpu_control0 = data;
case 0x0000/4:
case 0x0008/4:
{
const uint32_t index = (offset >> 1) & 1;
LOGMASKED(LOG_WRITES, "%s: CPU Control %d Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
m_cpu_control[index] = data;
break;
case 0x0008:
LOGMASKED(LOG_WRITES, "%s: CPU Control 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_cpu_control1 = data;
break;
case 0x0010:
}
case 0x0010/4:
LOGMASKED(LOG_WATCHDOG, "%s: Watchdog Timer Clear\n", machine().describe_context());
m_watchdog = 0;
break;
case 0x0028:
case 0x0028/4:
LOGMASKED(LOG_RPSS, "%s: RPSS Divider Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_rpss_divider = data;
m_rpss_divide_count = (int)(m_rpss_divider & 0xff);
m_rpss_divide_counter = m_rpss_divide_count;
m_rpss_increment = (m_rpss_divider >> 8) & 0xff;
break;
case 0x0030:
case 0x0030/4:
LOGMASKED(LOG_WRITES, "%s: R4000 EEPROM Write: CS:%d, SCK:%d, SO:%d\n", machine().describe_context(),
BIT(data, 1), BIT(data, 2), BIT(data, 3));
m_eeprom_ctrl = data;
m_eeprom->di_write(BIT(data, 3));
m_eeprom->cs_write(BIT(data, 1));
m_eeprom->clk_write(BIT(data, 2));
break;
case 0x0040:
case 0x0040/4:
LOGMASKED(LOG_WRITES, "%s: Refresh Count Preload Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_refcnt_preload = data;
break;
case 0x0080:
case 0x0080/4:
LOGMASKED(LOG_WRITES, "%s: GIO64 Arbitration Param Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_gio64_arb_param = data;
break;
case 0x0088:
case 0x0088/4:
LOGMASKED(LOG_WRITES, "%s: Arbiter CPU Time Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_arb_cpu_time = data;
break;
case 0x0098:
case 0x0098/4:
LOGMASKED(LOG_WRITES, "%s: Arbiter Long Burst Time Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_arb_burst_time = data;
break;
case 0x00c0:
LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 0 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_mem_config0 = data;
case 0x00c0/4:
case 0x00c8/4:
{
static const char* const s_mem_size[32] = {
"256Kx36", "512Kx36, 2 subbanks", "Invalid", "1Mx36", "Invalid", "Invalid", "Invalid", "2Mx36, 2 subbanks",
"Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "4Mx36",
"Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid",
"Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "Invalid", "8Mx36, 2 subbanks" };
const uint32_t index = (offset >> 1) & 1;
LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register %d Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Base Address: %02x\n", machine().describe_context(), index, (data >> 16) & 0xff);
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, SIMM Size: %02x (%s)\n", machine().describe_context(), index, (data >> 24) & 0x1f, s_mem_size[(data >> 24) & 0x1f]);
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Valid: %d\n", machine().describe_context(), index, BIT(data, 29));
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, # Subbanks: %d\n", machine().describe_context(), index, BIT(data, 30) + 1);
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Base Address: %02x\n", machine().describe_context(), index+1, data & 0xff);
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, SIMM Size: %02x (%s)\n", machine().describe_context(), index+1, (data >> 8) & 0x1f, s_mem_size[(data >> 8) & 0x1f]);
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, Valid: %d\n", machine().describe_context(), index+1, BIT(data, 13));
LOGMASKED(LOG_MEMCFG_EXT, "%s: Bank %d, # Subbanks: %d\n", machine().describe_context(), index+1, BIT(data, 14) + 1);
m_mem_config[index] = data;
break;
case 0x00c8:
LOGMASKED(LOG_MEMCFG, "%s: Memory Configuration Register 1 Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_mem_config1 = data;
break;
case 0x00d0:
}
case 0x00d0/4:
LOGMASKED(LOG_WRITES, "%s: CPU Memory Access Config Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_cpu_mem_access_config = data;
break;
case 0x00d8:
case 0x00d8/4:
LOGMASKED(LOG_WRITES, "%s: GIO Memory Access Config Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_gio_mem_access_config = data;
break;
case 0x00e8:
case 0x00e8/4:
LOGMASKED(LOG_WRITES, "%s: CPU Error Status Clear\n", machine().describe_context());
m_maincpu->set_input_line(MIPS3_IRQ4, CLEAR_LINE);
m_cpu_error_status = 0;
break;
case 0x00f8:
case 0x00f8/4:
LOGMASKED(LOG_WRITES, "%s: GIO Error Status Clear\n", machine().describe_context());
m_maincpu->set_input_line(MIPS3_IRQ4, CLEAR_LINE);
m_gio_error_status = 0;
break;
case 0x0100:
case 0x0100/4:
LOGMASKED(LOG_WRITES, "%s: System Semaphore Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_sys_semaphore = data;
break;
case 0x0108:
case 0x0108/4:
LOGMASKED(LOG_WRITES, "%s: GIO Lock Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_gio_lock = data;
break;
case 0x0110:
case 0x0110/4:
LOGMASKED(LOG_WRITES, "%s: EISA Lock Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_eisa_lock = data;
break;
case 0x0150:
case 0x0150/4:
LOGMASKED(LOG_WRITES, "%s: GIO64 Translation Address Mask Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_gio64_translate_mask = data;
break;
case 0x0158:
case 0x0158/4:
LOGMASKED(LOG_WRITES, "%s: GIO64 Translation Address Substitution Bits Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_gio64_substitute_bits = data;
break;
case 0x0160:
case 0x0160/4:
LOGMASKED(LOG_WRITES, "%s: DMA Interrupt Cause Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_int_cause = data;
break;
case 0x0168:
case 0x0168/4:
LOGMASKED(LOG_WRITES, "%s: DMA Control Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_control = data;
break;
case 0x0180:
case 0x0180/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 0 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry0_hi = data;
break;
case 0x0188:
case 0x0188/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 0 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry0_lo = data;
break;
case 0x0190:
case 0x0190/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 1 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry1_hi = data;
break;
case 0x0198:
case 0x0198/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 1 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry1_lo = data;
break;
case 0x01a0:
case 0x01a0/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 2 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry2_hi = data;
break;
case 0x01a8:
case 0x01a8/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 2 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry2_lo = data;
break;
case 0x01b0:
case 0x01b0/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 3 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry3_hi = data;
break;
case 0x01b8:
case 0x01b8/4:
LOGMASKED(LOG_WRITES, "%s: DMA TLB Entry 3 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry3_lo = data;
break;
case 0x2000:
case 0x2000/4:
LOGMASKED(LOG_WRITES, "%s: DMA Memory Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_mem_addr = data;
break;
case 0x2008:
case 0x2008/4:
LOGMASKED(LOG_WRITES, "%s: DMA Memory Address + Default Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_mem_addr = data;
break;
case 0x2010:
case 0x2010/4:
LOGMASKED(LOG_WRITES, "%s: DMA Line Count and Width Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_size = data;
break;
case 0x2018:
case 0x2018/4:
LOGMASKED(LOG_WRITES, "%s: DMA Line Zoom and Stride Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_stride = data;
break;
case 0x2020:
case 0x2020/4:
LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_gio64_addr = data;
break;
case 0x2028:
case 0x2028/4:
LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write + Start DMA: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_gio64_addr = data;
// Start DMA
m_dma_running = 1;
break;
case 0x2030:
case 0x2030/4:
LOGMASKED(LOG_WRITES, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_mode = data;
break;
case 0x2038:
case 0x2038/4:
LOGMASKED(LOG_WRITES, "%s: DMA Zoom Count + Byte Count Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_count = data;
break;
case 0x2040:
case 0x2040/4:
LOGMASKED(LOG_WRITES, "%s: DMA Start Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
// Start DMA
m_dma_running = 1;
break;
case 0x2070:
case 0x2070/4:
LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write + Default Params Write + Start DMA: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_gio64_addr = data;
// Start DMA
m_dma_running = 1;
break;
case 0x10000:
case 0x11000:
case 0x12000:
case 0x13000:
case 0x14000:
case 0x15000:
case 0x16000:
case 0x17000:
case 0x18000:
case 0x19000:
case 0x1a000:
case 0x1b000:
case 0x1c000:
case 0x1d000:
case 0x1e000:
case 0x1f000:
LOGMASKED(LOG_WRITES, "%s: Semaphore %d Write: %08x & %08x\n", machine().describe_context(), (offset - 0x10000) >> 12, data, mem_mask);
m_semaphore[(offset - 0x10000) >> 12] = data & 1;
case 0x10000/4:
case 0x11000/4:
case 0x12000/4:
case 0x13000/4:
case 0x14000/4:
case 0x15000/4:
case 0x16000/4:
case 0x17000/4:
case 0x18000/4:
case 0x19000/4:
case 0x1a000/4:
case 0x1b000/4:
case 0x1c000/4:
case 0x1d000/4:
case 0x1e000/4:
case 0x1f000/4:
{
const uint32_t index = (offset - 0x10000/4) >> 10;
LOGMASKED(LOG_WRITES, "%s: Semaphore %d Write: %08x & %08x\n", machine().describe_context(), index, data, mem_mask);
m_semaphore[index] = data & 1;
break;
}
default:
LOGMASKED(LOG_WRITES | LOG_UNKNOWN, "%s: Unmapped MC write: %08x: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset, data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_UNKNOWN, "%s: Unmapped MC write: %08x: %08x & %08x\n", machine().describe_context(), 0x1fa00000 + offset*4, data, mem_mask);
break;
}
}

View File

@ -13,12 +13,17 @@
#pragma once
#include "machine/eepromser.h"
class sgi_mc_device : public device_t
{
public:
sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner)
template <typename T, typename U>
sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&eeprom_tag)
: sgi_mc_device(mconfig, tag, owner, (uint32_t)0)
{
m_maincpu.set_tag(std::forward<T>(cpu_tag));
m_eeprom.set_tag(std::forward<U>(eeprom_tag));
}
sgi_mc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
@ -26,6 +31,8 @@ public:
DECLARE_READ32_MEMBER(read);
DECLARE_WRITE32_MEMBER(write);
void set_cpu_buserr(uint32_t address);
protected:
// device-level overrides
virtual void device_start() override;
@ -35,10 +42,12 @@ protected:
static const device_timer_id TIMER_RPSS = 0;
private:
// internal state
required_device<cpu_device> m_maincpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
emu_timer *m_rpss_timer;
uint32_t m_cpu_control0;
uint32_t m_cpu_control1;
uint32_t m_cpu_control[2];
uint32_t m_watchdog;
uint32_t m_sys_id;
uint32_t m_rpss_divider;
@ -47,8 +56,7 @@ private:
uint32_t m_gio64_arb_param;
uint32_t m_arb_cpu_time;
uint32_t m_arb_burst_time;
uint32_t m_mem_config0;
uint32_t m_mem_config1;
uint32_t m_mem_config[2];
uint32_t m_cpu_mem_access_config;
uint32_t m_gio_mem_access_config;
uint32_t m_cpu_error_addr;
@ -78,14 +86,11 @@ private:
uint32_t m_dma_mode;
uint32_t m_dma_count;
uint32_t m_dma_running;
uint32_t m_eeprom_ctrl;
uint32_t m_semaphore[16];
int m_rpss_divide_counter;
int m_rpss_divide_count;
uint8_t m_rpss_increment;
void update();
TIMER_CALLBACK_MEMBER(update_callback);
void timer_init();
};
DECLARE_DEVICE_TYPE(SGI_MC, sgi_mc_device)