-gio: Added basic SGI GIO slot device support to the Indy and Indigo 2 drivers. [Ryan Holtz]

-newport: Converted to GIO slot device and added 8-bit XL and 24-bit XL board support. [Ryan Holtz]
This commit is contained in:
mooglyguy 2019-05-05 14:58:45 +02:00 committed by MooglyGuy
parent 2ac59ff8ba
commit d64b1781d7
7 changed files with 554 additions and 105 deletions

View File

@ -951,6 +951,21 @@ if (BUSES["GAMATE"]~=null) then
end
---------------------------------------------------
--
--@src/devices/bus/gio/gio.h,BUSES["GIO"] = true
---------------------------------------------------
if (BUSES["GIO"]~=null) then
files {
MAME_DIR .. "src/devices/bus/gio/gio.cpp",
MAME_DIR .. "src/devices/bus/gio/gio.h",
MAME_DIR .. "src/devices/bus/gio/newport.cpp",
MAME_DIR .. "src/devices/bus/gio/newport.h",
}
end
---------------------------------------------------
--
--@src/devices/bus/hp_hil/hp_hil.h,BUSES["HPHIL"] = true

View File

@ -755,6 +755,7 @@ BUSES["GAMEBOY"] = true
BUSES["GAMEGEAR"] = true
BUSES["GBA"] = true
BUSES["GENERIC"] = true
BUSES["GIO"] = true
BUSES["HEXBUS"] = true
BUSES["HPHIL"] = true
BUSES["HPDIO"] = true
@ -3111,8 +3112,6 @@ files {
MAME_DIR .. "src/mame/drivers/indy_indigo2.cpp",
MAME_DIR .. "src/mame/video/light.cpp",
MAME_DIR .. "src/mame/video/light.h",
MAME_DIR .. "src/mame/video/newport.cpp",
MAME_DIR .. "src/mame/video/newport.h",
MAME_DIR .. "src/mame/video/crime.cpp",
MAME_DIR .. "src/mame/video/crime.h",
}

182
src/devices/bus/gio/gio.cpp Normal file
View File

@ -0,0 +1,182 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/***************************************************************************
gio.cpp - SGI GIO slot bus and GIO device emulation
***************************************************************************/
#include "emu.h"
// Display boards
#include "newport.h"
#include "gio.h"
void gio_cards(device_slot_interface &device)
{
device.option_add("xl8", GIO_XL8); /* SGI 8-bit XL board */
device.option_add("xl24", GIO_XL24); /* SGI 24-bit XL board */
}
DEFINE_DEVICE_TYPE(GIO_SLOT, gio_slot_device, "gio_slot", "SGI GIO Slot")
gio_slot_device::gio_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: gio_slot_device(mconfig, GIO_SLOT, tag, owner, clock)
{
}
gio_slot_device::gio_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, device_slot_interface(mconfig, *this)
, m_gio(*this, finder_base::DUMMY_TAG)
{
}
void gio_slot_device::device_validity_check(validity_checker &valid) const
{
device_t *const card(get_card_device());
if (card && !dynamic_cast<device_gio_card_interface *>(card))
osd_printf_error("Card device %s (%s) does not implement device_gio_card_interface\n", card->tag(), card->name());
}
void gio_slot_device::device_resolve_objects()
{
device_gio_card_interface *const gio_card(dynamic_cast<device_gio_card_interface *>(get_card_device()));
if (gio_card)
gio_card->set_gio(m_gio, tag());
}
void gio_slot_device::device_start()
{
device_t *const card(get_card_device());
if (card && !dynamic_cast<device_gio_card_interface *>(card))
throw emu_fatalerror("gio_slot_device: card device %s (%s) does not implement device_gio_card_interface\n", card->tag(), card->name());
}
DEFINE_DEVICE_TYPE(GIO, gio_device, "gio", "SGI GIO Bus")
device_memory_interface::space_config_vector gio_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(0, &m_space_config)
};
}
gio_device::gio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: gio_device(mconfig, GIO, tag, owner, clock)
{
}
gio_device::gio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, device_memory_interface(mconfig, *this)
, m_space_config("GIO Space", ENDIANNESS_BIG, 64, 32, 0, address_map_constructor())
, m_maincpu(*this, finder_base::DUMMY_TAG)
, m_hpc3(*this, finder_base::DUMMY_TAG)
{
}
void gio_device::device_resolve_objects()
{
}
void gio_device::device_start()
{
std::fill(std::begin(m_device_list), std::end(m_device_list), nullptr);
m_space = &space(0);
m_space->install_readwrite_handler(0x00000000, 0x003fffff, read64_delegate(FUNC(gio_device::no_gfx_r), this), write64_delegate(FUNC(gio_device::no_gfx_w), this));
m_space->install_readwrite_handler(0x00400000, 0x005fffff, read64_delegate(FUNC(gio_device::no_exp0_r), this), write64_delegate(FUNC(gio_device::no_exp0_w), this));
m_space->install_readwrite_handler(0x00600000, 0x009fffff, read64_delegate(FUNC(gio_device::no_exp1_r), this), write64_delegate(FUNC(gio_device::no_exp1_w), this));
}
READ64_MEMBER(gio_device::no_gfx_r) { return ~0ULL; }
READ64_MEMBER(gio_device::no_exp0_r) { return ~0ULL; }
READ64_MEMBER(gio_device::no_exp1_r) { return ~0ULL; }
WRITE64_MEMBER(gio_device::no_gfx_w) { }
WRITE64_MEMBER(gio_device::no_exp0_w) { }
WRITE64_MEMBER(gio_device::no_exp1_w) { }
READ64_MEMBER(gio_device::read)
{
return m_space->read_qword(offset << 3, mem_mask);
}
WRITE64_MEMBER(gio_device::write)
{
m_space->write_qword(offset << 3, data, mem_mask);
}
device_gio_card_interface *gio_device::get_gio_card(int slot)
{
if (slot < 0)
{
return nullptr;
}
if (m_device_list[slot])
{
return m_device_list[slot];
}
return nullptr;
}
void gio_device::add_gio_card(device_gio_card_interface::gio_slot_type_t slot_type, device_gio_card_interface *card)
{
m_device_list[slot_type] = card;
card->install_device();
}
device_gio_card_interface::device_gio_card_interface(const machine_config &mconfig, device_t &device)
: device_slot_card_interface(mconfig, device)
, m_gio(nullptr)
, m_gio_slottag(nullptr)
, m_slot_type(GIO_SLOT_COUNT)
{
}
device_gio_card_interface::~device_gio_card_interface()
{
}
void device_gio_card_interface::interface_validity_check(validity_checker &valid) const
{
}
void device_gio_card_interface::interface_pre_start()
{
device_slot_card_interface::interface_pre_start();
if (!m_gio)
{
fatalerror("Can't find SGI GIO device\n");
}
if (GIO_SLOT_COUNT == m_slot_type)
{
if (!m_gio->started())
throw device_missing_dependencies();
if (strcmp(m_gio_slottag, ":gio_gfx") == 0)
m_slot_type = GIO_SLOT_GFX;
else if (strcmp(m_gio_slottag, ":gio_exp0") == 0)
m_slot_type = GIO_SLOT_EXP0;
else if (strcmp(m_gio_slottag, ":gio_exp1") == 0)
m_slot_type = GIO_SLOT_EXP1;
else
fatalerror("Slot %s incorrectly named for SGI GIO graphics slot\n", m_gio_slottag);
m_gio->add_gio_card(m_slot_type, this);
}
}
void device_gio_card_interface::set_gio(gio_device *gio, const char *slottag)
{
m_gio = gio;
m_gio_slottag = slottag;
}

165
src/devices/bus/gio/gio.h Normal file
View File

@ -0,0 +1,165 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/***************************************************************************
gio.h - SGI GIO slot bus and GIO device emulation
***************************************************************************/
#ifndef MAME_BUS_GIO_GIO_H
#define MAME_BUS_GIO_GIO_H
#pragma once
#include "cpu/mips/r4000.h"
#include "machine/hpc3.h"
class gio_device;
class gio_slot_device : public device_t, public device_slot_interface
{
public:
// construction/destruction
template <typename T, typename U>
gio_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gio_tag, U &&opts, const char *dflt)
: gio_slot_device(mconfig, tag, owner, (uint32_t)0)
{
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
m_gio.set_tag(std::forward<T>(gio_tag));
}
gio_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
gio_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_validity_check(validity_checker &valid) const override;
virtual void device_resolve_objects() override;
virtual void device_start() override;
// configuration
required_device<gio_device> m_gio;
DECLARE_READ32_MEMBER(timeout_r);
DECLARE_WRITE32_MEMBER(timeout_w);
};
DECLARE_DEVICE_TYPE(GIO_SLOT, gio_slot_device)
// class representing interface-specific live GIO card
class device_gio_card_interface : public device_slot_card_interface
{
friend class gio_device;
public:
// construction/destruction
virtual ~device_gio_card_interface();
// inline configuration
void set_gio(gio_device *gio, const char *slottag);
virtual void mem_map(address_map &map) = 0;
protected:
device_gio_card_interface(const machine_config &mconfig, device_t &device);
enum gio_slot_type_t : uint32_t
{
GIO_SLOT_GFX,
GIO_SLOT_EXP0,
GIO_SLOT_EXP1,
GIO_SLOT_COUNT
};
virtual void interface_validity_check(validity_checker &valid) const override;
virtual void interface_pre_start() override;
virtual void install_device() = 0;
gio_device &gio() { assert(m_gio); return *m_gio; }
gio_device *m_gio;
const char *m_gio_slottag;
gio_slot_type_t m_slot_type;
};
class gio_device : public device_t,
public device_memory_interface
{
friend class device_gio_card_interface;
public:
// construction/destruction
template <typename T, typename U>
gio_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&hpc3_tag)
: gio_device(mconfig, tag, owner, (uint32_t)0)
{
set_cpu_tag(std::forward<T>(cpu_tag));
set_hpc3_tag(std::forward<U>(hpc3_tag));
}
gio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// inline configuration
template <typename T> void set_cpu_tag(T &&tag) { m_maincpu.set_tag(std::forward<T>(tag)); }
template <typename T> void set_hpc3_tag(T &&tag) { m_hpc3.set_tag(std::forward<T>(tag)); }
virtual space_config_vector memory_space_config() const override;
const address_space_config m_space_config;
void add_gio_card(device_gio_card_interface::gio_slot_type_t slot_type, device_gio_card_interface *card);
device_gio_card_interface *get_gio_card(int slot);
template<typename T> void install_graphics(T &device, void (T::*map)(class address_map &map), uint64_t unitmask = ~u64(0))
{
m_space->install_device(0x000000, 0x3fffff, device, map, unitmask);
}
template<typename T> void install_expansion(int index, T &device, void (T::*map)(class address_map &map), uint64_t unitmask = ~u64(0))
{
if (index == 0)
m_space->install_device(0x400000, 0x5fffff, device, map, unitmask);
else if (index == 1)
m_space->install_device(0x600000, 0x9fffff, device, map, unitmask);
else
fatalerror("Invalid SGIO GIO expansion slot index: %d\n", index);
}
hpc3_device* get_hpc3() { return m_hpc3.target(); }
DECLARE_READ64_MEMBER(read);
DECLARE_WRITE64_MEMBER(write);
protected:
gio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
// internal state
required_device<r4000_base_device> m_maincpu;
required_device<hpc3_device> m_hpc3;
address_space *m_space;
device_gio_card_interface *m_device_list[3];
private:
DECLARE_READ64_MEMBER(no_gfx_r);
DECLARE_READ64_MEMBER(no_exp0_r);
DECLARE_READ64_MEMBER(no_exp1_r);
DECLARE_WRITE64_MEMBER(no_gfx_w);
DECLARE_WRITE64_MEMBER(no_exp0_w);
DECLARE_WRITE64_MEMBER(no_exp1_w);
};
DECLARE_DEVICE_TYPE(GIO, gio_device)
void gio_cards(device_slot_interface &device);
#endif // MAME_BUS_GIO_GIO_H

View File

@ -27,7 +27,7 @@
*/
#include "emu.h"
#include "video/newport.h"
#include "newport.h"
#define LOG_UNKNOWN (1 << 0)
#define LOG_VC2 (1 << 1)
@ -43,23 +43,33 @@
#define VERBOSE (0)//(LOG_UNKNOWN | LOG_REX3 | LOG_COMMANDS | LOG_REJECTS)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(NEWPORT_VIDEO, newport_video_device, "newport_video", "SGI Newport graphics board")
DEFINE_DEVICE_TYPE(GIO_XL8, gio_xl8_device, "gio_xl8", "SGI 8-bit XL board")
DEFINE_DEVICE_TYPE(GIO_XL24, gio_xl24_device, "gio_xl24", "SGI 24-bit XL board")
newport_video_device::newport_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, NEWPORT_VIDEO, tag, owner, clock)
newport_base_device::newport_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t global_mask)
: device_t(mconfig, type, tag, owner, clock)
, device_palette_interface(mconfig, *this)
, m_maincpu(*this, finder_base::DUMMY_TAG)
, m_hpc3(*this, finder_base::DUMMY_TAG)
, device_gio_card_interface(mconfig, *this)
, m_global_mask(global_mask)
{
}
gio_xl8_device::gio_xl8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: newport_base_device(mconfig, GIO_XL8, tag, owner, clock, 0x000000ff)
{
}
gio_xl24_device::gio_xl24_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: newport_base_device(mconfig, GIO_XL24, tag, owner, clock, 0xffffffff)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void newport_video_device::device_start()
void newport_base_device::device_start()
{
m_rgbci = make_unique_clear<uint32_t[]>((1280+64) * (1024+64));
m_olay = make_unique_clear<uint32_t[]>((1280+64) * (1024+64));
@ -184,7 +194,7 @@ void newport_video_device::device_start()
// device_reset - device-specific reset
//-------------------------------------------------
void newport_video_device::device_reset()
void newport_base_device::device_reset()
{
memset(&m_vc2, 0, sizeof(vc2_t));
memset(&m_xmap0, 0, sizeof(xmap_t));
@ -206,8 +216,13 @@ void newport_video_device::device_reset()
#endif
}
void newport_base_device::mem_map(address_map &map)
{
map(0x000f0000, 0x000f1fff).rw(FUNC(newport_base_device::rex3_r), FUNC(newport_base_device::rex3_w));
}
#if ENABLE_NEWVIEW_LOG
void newport_video_device::start_logging()
void newport_base_device::start_logging()
{
uint16_t log_index = 0xffff;
char log_name_buf[128];
@ -234,7 +249,7 @@ void newport_video_device::start_logging()
fwrite(&m_cid[0], sizeof(uint32_t), (1280+64)*(1024+64), m_newview_log);
}
void newport_video_device::stop_logging()
void newport_base_device::stop_logging()
{
popmessage("Newport recording stopped.");
fclose(m_newview_log);
@ -242,7 +257,7 @@ void newport_video_device::stop_logging()
}
#endif
uint8_t newport_video_device::get_cursor_pixel(int x, int y)
uint8_t newport_base_device::get_cursor_pixel(int x, int y)
{
if (x < 0 || y < 0)
return 0;
@ -270,7 +285,7 @@ uint8_t newport_video_device::get_cursor_pixel(int x, int y)
}
}
uint32_t newport_video_device::screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect)
uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
bool enable_cursor = BIT(m_vc2.m_display_ctrl, DCR_CURSOR_FUNC_ENABLE_BIT) != 0
&& BIT(m_vc2.m_display_ctrl, DCR_CURSOR_ENABLE_BIT) != 0
@ -430,7 +445,7 @@ uint32_t newport_video_device::screen_update(screen_device &device, bitmap_rgb32
}
void newport_video_device::cmap0_write(uint32_t data)
void newport_base_device::cmap0_write(uint32_t data)
{
switch (m_rex3.m_dcb_reg_select)
{
@ -450,7 +465,7 @@ void newport_video_device::cmap0_write(uint32_t data)
}
}
uint32_t newport_video_device::cmap0_read()
uint32_t newport_base_device::cmap0_read()
{
switch (m_rex3.m_dcb_reg_select)
{
@ -458,15 +473,18 @@ uint32_t newport_video_device::cmap0_read()
LOGMASKED(LOG_CMAP0, "CMAP0 Status Read: %08x\n", 0x8);
return 0x8;
case 0x06: /* Revision */
LOGMASKED(LOG_CMAP0, "%s: CMAP0 Revision Read: CMAP Rev 1, Board Rev 3, 24bpp (00000002)\n", machine().describe_context());
return 0x00000002;
{
const uint32_t ret = get_cmap_revision();;
LOGMASKED(LOG_CMAP0, "CMAP0 Revision Read: %08x\n", ret);
return ret;
}
default:
LOGMASKED(LOG_CMAP0 | LOG_UNKNOWN, "Unknown CMAP0 Register %d Read\n", m_rex3.m_dcb_reg_select);
return 0;
}
}
uint32_t newport_video_device::cmap1_read()
uint32_t newport_base_device::cmap1_read()
{
switch (m_rex3.m_dcb_reg_select)
{
@ -474,15 +492,28 @@ uint32_t newport_video_device::cmap1_read()
LOGMASKED(LOG_CMAP1, "CMAP1 Status Read: %08x\n", 0x8);
return 0x8;
case 0x06: /* Revision */
LOGMASKED(LOG_CMAP1, "%s: CMAP1 Revision Read: CMAP Rev 1, Board Rev 3, 24bpp (00000002)\n", machine().describe_context());
return 0x00000002;
{
const uint32_t ret = get_cmap_revision();;
LOGMASKED(LOG_CMAP1, "CMAP1 Revision Read: %08x\n", ret);
return ret;
}
default:
LOGMASKED(LOG_CMAP1 | LOG_UNKNOWN, "Unknown CMAP0 Register %d Read\n", m_rex3.m_dcb_reg_select);
return 0;
}
}
uint32_t newport_video_device::xmap0_read()
uint32_t gio_xl8_device::get_cmap_revision()
{
return 0xa1;
}
uint32_t gio_xl24_device::get_cmap_revision()
{
return 0x02;
}
uint32_t newport_base_device::xmap0_read()
{
switch (m_rex3.m_dcb_reg_select)
{
@ -490,8 +521,11 @@ uint32_t newport_video_device::xmap0_read()
LOGMASKED(LOG_XMAP0, "XMAP0 Config Read: %08x\n", m_xmap0.m_config);
return m_xmap0.m_config;
case 1:
LOGMASKED(LOG_XMAP0, "%s: XMAP0 Revision Read: %08x\n", machine().describe_context(), 3);
return 3;
{
const uint32_t ret = get_xmap_revision();
LOGMASKED(LOG_XMAP0, "XMAP0 Revision Read: %08x\n", ret);
return ret;
}
case 2:
LOGMASKED(LOG_XMAP0, "XMAP0 FIFO Availability Read: %08x\n", 0x2);
return 0x2;
@ -540,7 +574,7 @@ uint32_t newport_video_device::xmap0_read()
return 0;
}
void newport_video_device::xmap0_write(uint32_t data)
void newport_base_device::xmap0_write(uint32_t data)
{
switch (m_rex3.m_dcb_reg_select)
{
@ -579,7 +613,7 @@ void newport_video_device::xmap0_write(uint32_t data)
}
}
uint32_t newport_video_device::xmap1_read()
uint32_t newport_base_device::xmap1_read()
{
switch (m_rex3.m_dcb_reg_select)
{
@ -587,8 +621,11 @@ uint32_t newport_video_device::xmap1_read()
LOGMASKED(LOG_XMAP1, "XMAP1 Config Read: %08x\n", m_xmap1.m_config);
return m_xmap1.m_config;
case 1:
LOGMASKED(LOG_XMAP1, "%s: XMAP1 Revision Read: %08x\n", machine().describe_context(), 3);
return 3;
{
const uint32_t ret = get_xmap_revision();
LOGMASKED(LOG_XMAP1, "XMAP1 Revision Read: %08x\n", ret);
return ret;
}
case 2:
LOGMASKED(LOG_XMAP1, "XMAP1 FIFO Availability Read: %08x\n", 0x02);
return 0x2;
@ -637,7 +674,7 @@ uint32_t newport_video_device::xmap1_read()
return 0;
}
void newport_video_device::xmap1_write(uint32_t data)
void newport_base_device::xmap1_write(uint32_t data)
{
switch (m_rex3.m_dcb_reg_select)
{
@ -676,7 +713,17 @@ void newport_video_device::xmap1_write(uint32_t data)
}
}
uint32_t newport_video_device::vc2_read()
uint32_t gio_xl8_device::get_xmap_revision()
{
return 1;
}
uint32_t gio_xl24_device::get_xmap_revision()
{
return 3;
}
uint32_t newport_base_device::vc2_read()
{
switch (m_rex3.m_dcb_reg_select)
{
@ -758,7 +805,7 @@ uint32_t newport_video_device::vc2_read()
}
}
void newport_video_device::vc2_write(uint32_t data)
void newport_base_device::vc2_write(uint32_t data)
{
switch (m_rex3.m_xfer_width)
{
@ -889,19 +936,19 @@ void newport_video_device::vc2_write(uint32_t data)
}
}
WRITE_LINE_MEMBER(newport_video_device::vblank_w)
WRITE_LINE_MEMBER(newport_base_device::vblank_w)
{
if (state)
{
if (BIT(m_vc2.m_display_ctrl, 0))
{
m_rex3.m_status |= 0x20;
m_hpc3->raise_local_irq(0, ioc2_device::INT3_LOCAL0_GRAPHICS);
m_gio->get_hpc3()->raise_local_irq(0, ioc2_device::INT3_LOCAL0_GRAPHICS);
}
}
}
READ64_MEMBER(newport_video_device::rex3_r)
READ64_MEMBER(newport_base_device::rex3_r)
{
uint64_t ret = 0;
switch (offset & ~(0x800/8))
@ -1319,7 +1366,7 @@ READ64_MEMBER(newport_video_device::rex3_r)
LOGMASKED(LOG_REX3, "REX3 Status Read: %08x\n", m_rex3.m_status);
uint32_t old_status = m_rex3.m_status;
m_rex3.m_status = 0;
m_hpc3->lower_local_irq(0, ioc2_device::INT3_LOCAL0_GRAPHICS);
m_gio->get_hpc3()->lower_local_irq(0, ioc2_device::INT3_LOCAL0_GRAPHICS);
ret |= (uint64_t)(old_status | 3) << 32;
}
if (ACCESSING_BITS_0_31)
@ -1335,7 +1382,7 @@ READ64_MEMBER(newport_video_device::rex3_r)
return ret;
}
void newport_video_device::write_pixel(uint32_t color)
void newport_base_device::write_pixel(uint32_t color)
{
const bool shade = BIT(m_rex3.m_draw_mode0, 18);
const bool rgbmode = BIT(m_rex3.m_draw_mode1, 15);
@ -1345,7 +1392,7 @@ void newport_video_device::write_pixel(uint32_t color)
write_pixel(m_rex3.m_x_start_i, m_rex3.m_y_start_i, color);
}
bool newport_video_device::pixel_clip_pass(int16_t x, int16_t y)
bool newport_base_device::pixel_clip_pass(int16_t x, int16_t y)
{
bool mask0_pass = true;
if (BIT(m_rex3.m_clip_mode, 0))
@ -1428,7 +1475,7 @@ bool newport_video_device::pixel_clip_pass(int16_t x, int16_t y)
return true;
}
void newport_video_device::store_pixel(uint32_t *dest_buf, uint32_t src)
void newport_base_device::store_pixel(uint32_t *dest_buf, uint32_t src)
{
if (BIT(m_rex3.m_draw_mode1, 5))
{
@ -1450,28 +1497,30 @@ void newport_video_device::store_pixel(uint32_t *dest_buf, uint32_t src)
const uint32_t dst = *dest_buf;
*dest_buf &= ~m_rex3.m_write_mask;
const uint32_t write_mask = m_rex3.m_write_mask & m_global_mask;
switch ((m_rex3.m_draw_mode1 >> 28) & 15)
{
case 0: break;
case 1: *dest_buf |= (src & dst) & m_rex3.m_write_mask; break;
case 2: *dest_buf |= (src & ~dst) & m_rex3.m_write_mask; break;
case 3: *dest_buf |= (src) & m_rex3.m_write_mask; break;
case 4: *dest_buf |= (~src & dst) & m_rex3.m_write_mask; break;
case 5: *dest_buf |= (dst) & m_rex3.m_write_mask; break;
case 6: *dest_buf |= (src ^ dst) & m_rex3.m_write_mask; break;
case 7: *dest_buf |= (src | dst) & m_rex3.m_write_mask; break;
case 8: *dest_buf |= ~(src | dst) & m_rex3.m_write_mask; break;
case 9: *dest_buf |= ~(src ^ dst) & m_rex3.m_write_mask; break;
case 10: *dest_buf |= ~(dst) & m_rex3.m_write_mask; break;
case 11: *dest_buf |= (src | ~dst) & m_rex3.m_write_mask; break;
case 12: *dest_buf |= ~(src) & m_rex3.m_write_mask; break;
case 13: *dest_buf |= (~src | dst) & m_rex3.m_write_mask; break;
case 14: *dest_buf |= ~(src & dst) & m_rex3.m_write_mask; break;
case 15: *dest_buf |= 0xffffff & m_rex3.m_write_mask; break;
case 0: break;
case 1: *dest_buf |= (src & dst) & write_mask; break;
case 2: *dest_buf |= (src & ~dst) & write_mask; break;
case 3: *dest_buf |= (src) & write_mask; break;
case 4: *dest_buf |= (~src & dst) & write_mask; break;
case 5: *dest_buf |= (dst) & write_mask; break;
case 6: *dest_buf |= (src ^ dst) & write_mask; break;
case 7: *dest_buf |= (src | dst) & write_mask; break;
case 8: *dest_buf |= ~(src | dst) & write_mask; break;
case 9: *dest_buf |= ~(src ^ dst) & write_mask; break;
case 10: *dest_buf |= ~(dst) & write_mask; break;
case 11: *dest_buf |= (src | ~dst) & write_mask; break;
case 12: *dest_buf |= ~(src) & write_mask; break;
case 13: *dest_buf |= (~src | dst) & write_mask; break;
case 14: *dest_buf |= ~(src & dst) & write_mask; break;
case 15: *dest_buf |= 0xffffff & write_mask; break;
}
}
void newport_video_device::write_pixel(int16_t x, int16_t y, uint32_t color)
void newport_base_device::write_pixel(int16_t x, int16_t y, uint32_t color)
{
if (!pixel_clip_pass(x, y))
{
@ -1503,7 +1552,7 @@ void newport_video_device::write_pixel(int16_t x, int16_t y, uint32_t color)
}
}
uint32_t newport_video_device::get_rgb_color(int16_t x, int16_t y)
uint32_t newport_base_device::get_rgb_color(int16_t x, int16_t y)
{
static const uint8_t s_bayer[4][4] = { { 0, 12, 3, 15 },{ 8, 4, 11, 7 },{ 2, 14, 1, 13 },{ 10, 6, 9, 5 } };
@ -1608,7 +1657,7 @@ uint32_t newport_video_device::get_rgb_color(int16_t x, int16_t y)
}
}
void newport_video_device::do_v_iline(uint32_t color)
void newport_base_device::do_v_iline(uint32_t color)
{
const int16_t x1 = m_rex3.m_x_start_i;
int16_t y1 = m_rex3.m_y_start_i;
@ -1649,7 +1698,7 @@ void newport_video_device::do_v_iline(uint32_t color)
write_y_start(y1 << 11);
}
void newport_video_device::do_h_iline(uint32_t color)
void newport_base_device::do_h_iline(uint32_t color)
{
int16_t x1 = m_rex3.m_x_start_i;
const int16_t y1 = m_rex3.m_y_start_i;
@ -1690,7 +1739,7 @@ void newport_video_device::do_h_iline(uint32_t color)
write_y_start(y1 << 11);
}
void newport_video_device::do_iline(uint32_t color)
void newport_base_device::do_iline(uint32_t color)
{
int16_t x1 = m_rex3.m_x_start_i;
int16_t y1 = m_rex3.m_y_start_i;
@ -1822,7 +1871,7 @@ void newport_video_device::do_iline(uint32_t color)
write_y_start(y1 << 11);
}
uint32_t newport_video_device::do_pixel_read()
uint32_t newport_base_device::do_pixel_read()
{
if (m_rex3.m_xy_start_i == m_rex3.m_xy_end_i)
m_rex3.m_read_active = false;
@ -1841,7 +1890,7 @@ uint32_t newport_video_device::do_pixel_read()
return ret;
}
uint64_t newport_video_device::do_pixel_word_read()
uint64_t newport_base_device::do_pixel_word_read()
{
const uint16_t x_start = (uint16_t)(m_rex3.m_xy_start_i >> 16);
const uint16_t x_end = (uint16_t)(m_rex3.m_xy_end_i >> 16);
@ -1915,14 +1964,14 @@ uint64_t newport_video_device::do_pixel_word_read()
return ret;
}
void newport_video_device::iterate_shade()
void newport_base_device::iterate_shade()
{
m_rex3.m_color_red += m_rex3.m_slope_red;
m_rex3.m_color_green += m_rex3.m_slope_green;
m_rex3.m_color_blue += m_rex3.m_slope_blue;
}
void newport_video_device::do_rex3_command()
void newport_base_device::do_rex3_command()
{
static const char* const s_opcode_str[4] = { "Noop", "Read", "Draw", "Scr2Scr" };
static const char* const s_adrmode_str[8] = {
@ -2272,7 +2321,7 @@ void newport_video_device::do_rex3_command()
}
}
void newport_video_device::write_x_start(int32_t val)
void newport_base_device::write_x_start(int32_t val)
{
m_rex3.m_x_start = val & 0x07ffff80;
m_rex3.m_x_start_i = (int16_t)(val >> 11);
@ -2280,7 +2329,7 @@ void newport_video_device::write_x_start(int32_t val)
m_rex3.m_xy_start_i = (m_rex3.m_xy_start_i & 0x0000ffff) | (m_rex3.m_x_start_i << 16);
}
void newport_video_device::write_y_start(int32_t val)
void newport_base_device::write_y_start(int32_t val)
{
m_rex3.m_y_start = val & 0x07ffff80;
m_rex3.m_y_start_i = (int16_t)(val >> 11);
@ -2288,7 +2337,7 @@ void newport_video_device::write_y_start(int32_t val)
m_rex3.m_xy_start_i = (m_rex3.m_xy_start_i & 0xffff0000) | (uint16_t)m_rex3.m_y_start_i;
}
void newport_video_device::write_x_end(int32_t val)
void newport_base_device::write_x_end(int32_t val)
{
m_rex3.m_x_end = val & 0x07ffff80;
m_rex3.m_x_end_i = (int16_t)(val >> 11);
@ -2296,7 +2345,7 @@ void newport_video_device::write_x_end(int32_t val)
m_rex3.m_xy_end_i = (m_rex3.m_xy_end_i & 0x0000ffff) | (m_rex3.m_x_end_i << 16);
}
void newport_video_device::write_y_end(int32_t val)
void newport_base_device::write_y_end(int32_t val)
{
m_rex3.m_y_end = val & 0x07ffff80;
m_rex3.m_y_end_i = (int16_t)(val >> 11);
@ -2304,7 +2353,7 @@ void newport_video_device::write_y_end(int32_t val)
m_rex3.m_xy_end_i = (m_rex3.m_xy_end_i & 0xffff0000) | (uint16_t)m_rex3.m_y_end_i;
}
WRITE64_MEMBER(newport_video_device::rex3_w)
WRITE64_MEMBER(newport_base_device::rex3_w)
{
#if ENABLE_NEWVIEW_LOG
if (m_newview_log != nullptr)
@ -2806,6 +2855,7 @@ WRITE64_MEMBER(newport_video_device::rex3_w)
{
LOGMASKED(LOG_REX3, "REX3 Red/CI Full State Write: %08x\n", (uint32_t)(data >> 32));
m_rex3.m_color_red = (int32_t)((data >> 32) & 0xffffff);
m_rex3.m_color_i = (uint32_t)(m_rex3.m_color_red >> 11) & 0x00000fff;
}
if (ACCESSING_BITS_0_31)
{
@ -3107,3 +3157,20 @@ WRITE64_MEMBER(newport_video_device::rex3_w)
do_rex3_command();
}
}
void newport_base_device::install_device()
{
m_gio->install_graphics(*this, &newport_base_device::mem_map);
}
void newport_base_device::device_add_mconfig(machine_config &config)
{
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_size(1280+64, 1024+64);
screen.set_visarea(0, 1279, 0, 1023);
screen.set_screen_update(FUNC(newport_base_device::screen_update));
screen.screen_vblank().set(FUNC(newport_base_device::vblank_w));
}

View File

@ -4,28 +4,25 @@
SGI "Newport" graphics board used in the Indy and some Indigo2s
*/
#ifndef MAME_VIDEO_NEWPORT_H
#define MAME_VIDEO_NEWPORT_H
#ifndef MAME_BUS_GIO_NEWPORT_H
#define MAME_BUS_GIO_NEWPORT_H
#pragma once
#include "cpu/mips/r4000.h"
#include "machine/hpc3.h"
#include "gio.h"
#include "screen.h"
#define ENABLE_NEWVIEW_LOG (0)
#define ENABLE_NEWVIEW_LOG (1)
class newport_video_device : public device_t, public device_palette_interface
class newport_base_device : public device_t
, public device_palette_interface
, public device_gio_card_interface
{
public:
template <typename T, typename U>
newport_video_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&cpu_tag, U &&hpc3_tag)
: newport_video_device(mconfig, tag, owner, (uint32_t)0) // TODO: Use actual pixel clock
{
m_maincpu.set_tag(std::forward<T>(cpu_tag));
m_hpc3.set_tag(std::forward<U>(hpc3_tag));
}
newport_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t global_mask);
newport_video_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// device_gio_slot_interface overrides
virtual void install_device() override;
DECLARE_READ64_MEMBER(rex3_r);
DECLARE_WRITE64_MEMBER(rex3_w);
@ -35,11 +32,13 @@ public:
DECLARE_WRITE_LINE_MEMBER(vblank_w);
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual uint32_t palette_entries() const override { return 0x2000; }
virtual void device_start() override;
virtual void device_reset() override;
private:
void mem_map(address_map &map) override;
enum
{
DCR_CURSOR_FUNC_ENABLE_BIT = 4,
@ -194,6 +193,9 @@ private:
void iterate_shade();
virtual uint32_t get_cmap_revision() = 0;
virtual uint32_t get_xmap_revision() = 0;
uint32_t get_rgb_color(int16_t x, int16_t y);
void do_v_iline(uint32_t color);
@ -203,9 +205,6 @@ private:
uint64_t do_pixel_word_read();
void do_rex3_command();
required_device<r4000_base_device> m_maincpu;
required_device<hpc3_device> m_hpc3;
vc2_t m_vc2;
xmap_t m_xmap0;
xmap_t m_xmap1;
@ -215,6 +214,7 @@ private:
std::unique_ptr<uint32_t[]> m_pup;
std::unique_ptr<uint32_t[]> m_cid;
cmap_t m_cmap0;
uint32_t m_global_mask;
#if ENABLE_NEWVIEW_LOG
void start_logging();
@ -224,7 +224,27 @@ private:
#endif
};
DECLARE_DEVICE_TYPE(NEWPORT_VIDEO, newport_video_device)
class gio_xl8_device : public newport_base_device
{
public:
gio_xl8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
protected:
virtual uint32_t get_cmap_revision() override;
virtual uint32_t get_xmap_revision() override;
};
#endif // MAME_VIDEO_NEWPORT_H
class gio_xl24_device : public newport_base_device
{
public:
gio_xl24_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U);
protected:
virtual uint32_t get_cmap_revision() override;
virtual uint32_t get_xmap_revision() override;
};
DECLARE_DEVICE_TYPE(GIO_XL8, gio_xl8_device)
DECLARE_DEVICE_TYPE(GIO_XL24, gio_xl24_device)
#endif // MAME_BUS_GIO_NEWPORT_H

View File

@ -54,6 +54,8 @@
#include "emu.h"
#include "bus/gio/gio.h"
#include "cpu/mips/r4000.h"
#include "machine/hpc3.h"
@ -64,8 +66,6 @@
#include "sound/cdda.h"
#include "video/newport.h"
#include "emupal.h"
#include "screen.h"
@ -78,8 +78,11 @@ public:
, m_mainram(*this, "mainram")
, m_mem_ctrl(*this, "memctrl")
, m_scsi_ctrl(*this, "scsibus:0:wd33c93")
, m_newport(*this, "newport")
, m_hpc3(*this, "hpc3")
, m_gio(*this, "gio")
, m_gio_gfx(*this, "gio_gfx")
, m_gio_exp0(*this, "gio_exp0")
, m_gio_exp1(*this, "gio_exp1")
{
}
@ -100,12 +103,15 @@ protected:
static void scsi_devices(device_slot_interface &device);
required_device<cpu_device> m_maincpu;
required_device<r4000_base_device> m_maincpu;
required_shared_ptr<uint64_t> m_mainram;
required_device<sgi_mc_device> m_mem_ctrl;
required_device<wd33c93b_device> m_scsi_ctrl;
required_device<newport_video_device> m_newport;
required_device<hpc3_device> m_hpc3;
optional_device<gio_device> m_gio;
optional_device<gio_slot_device> m_gio_gfx;
optional_device<gio_slot_device> m_gio_exp0;
optional_device<gio_slot_device> m_gio_exp1;
};
class ip24_state : public ip22_state
@ -154,7 +160,7 @@ void ip22_state::ip22_map(address_map &map)
map(0x00000000, 0x0007ffff).bankrw("bank1"); /* mirror of first 512k of main RAM */
map(0x00080000, 0x0009ffff).r(FUNC(ip22_state::eisa_io_r));
map(0x08000000, 0x0fffffff).share("mainram").ram().w(FUNC(ip22_state::write_ram)); /* 128 MB of main RAM */
map(0x1f0f0000, 0x1f0f1fff).rw(m_newport, FUNC(newport_video_device::rex3_r), FUNC(newport_video_device::rex3_w));
map(0x1f000000, 0x1f9fffff).rw(m_gio, FUNC(gio_device::read), FUNC(gio_device::write));
map(0x1fa00000, 0x1fa1ffff).rw(m_mem_ctrl, FUNC(sgi_mc_device::read), FUNC(sgi_mc_device::write));
map(0x1fb80000, 0x1fbfffff).m(m_hpc3, FUNC(hpc3_device::map));
map(0x1fc00000, 0x1fc7ffff).rom().region("user1", 0);
@ -200,17 +206,6 @@ void ip22_state::scsi_devices(device_slot_interface &device)
void ip22_state::ip22_base(machine_config &config)
{
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_size(1280+64, 1024+64);
screen.set_visarea(0, 1279, 0, 1023);
screen.set_screen_update("newport", FUNC(newport_video_device::screen_update));
screen.screen_vblank().set(m_newport, FUNC(newport_video_device::vblank_w));
NEWPORT_VIDEO(config, m_newport, m_maincpu, m_hpc3);
SGI_MC(config, m_mem_ctrl, m_maincpu, ":hpc3:eeprom", m_hpc3);
NSCSI_BUS(config, "scsibus", 0);
@ -223,6 +218,12 @@ void ip22_state::ip22_base(machine_config &config)
NSCSI_CONNECTOR(config, "scsibus:5", scsi_devices, nullptr, false);
NSCSI_CONNECTOR(config, "scsibus:6", scsi_devices, "cdrom", false);
NSCSI_CONNECTOR(config, "scsibus:7", scsi_devices, nullptr, false);
// GIO
GIO(config, m_gio, m_maincpu, m_hpc3);
GIO_SLOT(config, m_gio_gfx, m_gio, gio_cards, nullptr);
GIO_SLOT(config, m_gio_exp0, m_gio, gio_cards, nullptr);
GIO_SLOT(config, m_gio_exp1, m_gio, gio_cards, nullptr);
}
void ip22_state::ip225015(machine_config &config)