mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
sgi: Various minor fixes and improvements, nw
This commit is contained in:
parent
fed9a5b345
commit
48c0c4a269
@ -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",
|
||||
|
@ -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 )
|
||||
|
@ -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)
|
||||
|
@ -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
725
src/mame/machine/hpc1.cpp
Normal 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
136
src/mame/machine/hpc1.h
Normal 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
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user