-indy_indigo2: Switch to using new R4x00 core, nw

-sgi_mc_device: Preliminary (broken) VDMA, nw

-newport: Various changes: [Ryan Holtz]
 * Switched to using a buffer of bytes, and doing the palette lookup in screen_update.
 * Added preliminary FB readback support.
 * Added preliminary line-drawing support.
 * Added support for more commands. Should eventually be handled in a different way than now.
This commit is contained in:
mooglyguy 2019-02-09 20:01:50 +01:00 committed by MooglyGuy
parent 9a22769399
commit ac124a896b
5 changed files with 420 additions and 160 deletions

View File

@ -61,7 +61,7 @@
#include "emu.h"
#include "cpu/mips/mips3.h"
#include "cpu/mips/r4000.h"
#include "machine/hpc3.h"
#include "machine/nscsi_bus.h"
@ -107,7 +107,7 @@ protected:
static void scsi_devices(device_slot_interface &device);
required_device<mips3_device> m_maincpu;
required_device<cpu_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;
@ -173,7 +173,7 @@ void ip22_state::machine_reset()
// set up low RAM mirror
membank("bank1")->set_base(m_mainram);
m_maincpu->mips3drc_set_options(MIPS3DRC_COMPATIBLE_OPTIONS | MIPS3DRC_CHECK_OVERFLOWS);
//m_maincpu->mips3drc_set_options(MIPS3DRC_COMPATIBLE_OPTIONS | MIPS3DRC_CHECK_OVERFLOWS);
}
static INPUT_PORTS_START( ip225015 )
@ -238,9 +238,9 @@ void ip22_state::ip225015(machine_config &config)
{
ip22_base(config);
R5000BE(config, m_maincpu, 50000000*3);
m_maincpu->set_icache_size(32768);
m_maincpu->set_dcache_size(32768);
R4000(config, m_maincpu, 50000000*3);
//m_maincpu->set_icache_size(32768);
//m_maincpu->set_dcache_size(32768);
m_maincpu->set_addrmap(AS_PROGRAM, &ip22_state::ip22_map);
SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl);
@ -250,9 +250,9 @@ void ip22_state::ip224613(machine_config &config)
{
ip22_base(config);
R4600BE(config, m_maincpu, 33333333*4);
m_maincpu->set_icache_size(32768);
m_maincpu->set_dcache_size(32768);
R4600(config, m_maincpu, 33333333*4);
//m_maincpu->set_icache_size(32768);
//m_maincpu->set_dcache_size(32768);
m_maincpu->set_addrmap(AS_PROGRAM, &ip22_state::ip22_map);
SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl);
@ -269,9 +269,9 @@ void ip24_state::ip244415(machine_config &config)
{
ip22_base(config);
R4400BE(config, m_maincpu, 50000000*3);
m_maincpu->set_icache_size(32768);
m_maincpu->set_dcache_size(32768);
R4400(config, m_maincpu, 50000000*3);
//m_maincpu->set_icache_size(32768);
//m_maincpu->set_dcache_size(32768);
m_maincpu->set_addrmap(AS_PROGRAM, &ip24_state::ip22_map);
NSCSI_BUS(config, "scsibus2", 0);

View File

@ -19,9 +19,10 @@
#define LOG_MEMCFG (1 << 5)
#define LOG_MEMCFG_EXT (1 << 6)
#define LOG_EEPROM (1 << 7)
#define LOG_DMA (1 << 8)
#define LOG_DEFAULT (LOG_READS | LOG_WRITES | LOG_RPSS | LOG_WATCHDOG | LOG_UNKNOWN)
#define VERBOSE (0)
#define VERBOSE (LOG_DMA)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(SGI_MC, sgi_mc_device, "sgi_mc", "SGI Memory Controller")
@ -52,14 +53,6 @@ sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, dev
, 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)
@ -117,14 +110,8 @@ void sgi_mc_device::device_start()
save_item(NAME(m_gio64_substitute_bits));
save_item(NAME(m_dma_int_cause));
save_item(NAME(m_dma_control));
save_item(NAME(m_dma_tlb_entry0_hi));
save_item(NAME(m_dma_tlb_entry0_lo));
save_item(NAME(m_dma_tlb_entry1_hi));
save_item(NAME(m_dma_tlb_entry1_lo));
save_item(NAME(m_dma_tlb_entry2_hi));
save_item(NAME(m_dma_tlb_entry2_lo));
save_item(NAME(m_dma_tlb_entry3_hi));
save_item(NAME(m_dma_tlb_entry3_lo));
save_item(NAME(m_dma_tlb_entry_hi));
save_item(NAME(m_dma_tlb_entry_lo));
save_item(NAME(m_rpss_counter));
save_item(NAME(m_dma_mem_addr));
save_item(NAME(m_dma_size));
@ -166,14 +153,11 @@ void sgi_mc_device::device_reset()
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;
for (int i = 0; i < 4; i++)
{
m_dma_tlb_entry_hi[i] = 0;
m_dma_tlb_entry_lo[i] = 0;
}
m_rpss_counter = 0;
m_dma_mem_addr = 0;
m_dma_size = 0;
@ -200,6 +184,19 @@ void sgi_mc_device::set_cpu_buserr(uint32_t address)
m_cpu_error_status |= 0x0000000f;
}
uint32_t sgi_mc_device::dma_translate(uint32_t address)
{
for (int entry = 0; entry < 4; entry++)
{
if ((address & 0xfff00000) == (m_dma_tlb_entry_hi[entry] & 0xfff00000))
{
const uint32_t offset = address - m_dma_tlb_entry_hi[entry];
return ((m_dma_tlb_entry_lo[entry] &~ 0x3f) << 6) + offset;
}
}
return 0;
}
READ32_MEMBER(sgi_mc_device::read)
{
switch (offset & ~1)
@ -283,63 +280,63 @@ READ32_MEMBER(sgi_mc_device::read)
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/4:
LOGMASKED(LOG_READS, "%s: DMA Interrupt Cause: %08x & %08x\n", machine().describe_context(), m_dma_int_cause, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Interrupt Cause: %08x & %08x\n", machine().describe_context(), m_dma_int_cause, mem_mask);
return m_dma_int_cause;
case 0x0168/4:
LOGMASKED(LOG_READS, "%s: DMA Control Read: %08x & %08x\n", machine().describe_context(), m_dma_control, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Control Read: %08x & %08x\n", machine().describe_context(), m_dma_control, mem_mask);
return m_dma_control;
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 0 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[0], mem_mask);
return m_dma_tlb_entry_hi[0];
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 0 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[0], mem_mask);
return m_dma_tlb_entry_lo[0];
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 1 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[1], mem_mask);
return m_dma_tlb_entry_hi[1];
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 1 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[1], mem_mask);
return m_dma_tlb_entry_lo[1];
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 2 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[2], mem_mask);
return m_dma_tlb_entry_hi[2];
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 2 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[2], mem_mask);
return m_dma_tlb_entry_lo[2];
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 3 High Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_hi[3], mem_mask);
return m_dma_tlb_entry_hi[3];
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;
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA TLB Entry 3 Low Read: %08x & %08x\n", machine().describe_context(), m_dma_tlb_entry_lo[3], mem_mask);
return m_dma_tlb_entry_lo[3];
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/4:
case 0x2008/4:
LOGMASKED(LOG_READS, "%s: DMA Memory Address Read: %08x & %08x\n", machine().describe_context(), m_dma_mem_addr, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Memory Address Read: %08x & %08x\n", machine().describe_context(), m_dma_mem_addr, mem_mask);
return m_dma_mem_addr;
case 0x2010/4:
LOGMASKED(LOG_READS, "%s: DMA Line Count and Width Read: %08x & %08x\n", machine().describe_context(), m_dma_size, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Line Count and Width Read: %08x & %08x\n", machine().describe_context(), m_dma_size, mem_mask);
return m_dma_size;
case 0x2018/4:
LOGMASKED(LOG_READS, "%s: DMA Line Zoom and Stride Read: %08x & %08x\n", machine().describe_context(), m_dma_stride, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Line Zoom and Stride Read: %08x & %08x\n", machine().describe_context(), m_dma_stride, mem_mask);
return m_dma_stride;
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);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA GIO64 Address Read: %08x & %08x\n", machine().describe_context(), m_dma_gio64_addr, mem_mask);
return m_dma_gio64_addr;
case 0x2030/4:
LOGMASKED(LOG_READS, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), m_dma_mode, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), m_dma_mode, mem_mask);
return m_dma_mode;
case 0x2038/4:
LOGMASKED(LOG_READS, "%s: DMA Zoom Count Read: %08x & %08x\n", machine().describe_context(), m_dma_count, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Zoom Count Read: %08x & %08x\n", machine().describe_context(), m_dma_count, mem_mask);
return m_dma_count;
case 0x2040/4:
LOGMASKED(LOG_READS, "%s: DMA Start Read\n", machine().describe_context());
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Start Read\n", machine().describe_context());
return 0;
case 0x2048/4:
LOGMASKED(LOG_READS, "%s: VDMA Running Read: %08x & %08x\n", machine().describe_context(), m_dma_running, mem_mask);
LOGMASKED(LOG_READS | LOG_DMA, "%s: VDMA Running Read: %08x & %08x\n", machine().describe_context(), m_dma_running, mem_mask);
if (m_dma_running == 1)
{
m_dma_running = 0;
@ -486,86 +483,105 @@ WRITE32_MEMBER( sgi_mc_device::write )
m_gio64_substitute_bits = data;
break;
case 0x0160/4:
LOGMASKED(LOG_WRITES, "%s: DMA Interrupt Cause Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Interrupt Cause Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_int_cause = data;
break;
case 0x0168/4:
LOGMASKED(LOG_WRITES, "%s: DMA Control Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Control Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_control = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 0 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_hi[0] = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 0 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_lo[0] = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 1 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_hi[1] = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 1 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_lo[1] = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 2 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_hi[2] = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 2 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_lo[2] = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 3 High Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_hi[3] = data;
break;
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;
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA TLB Entry 3 Low Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_tlb_entry_lo[3] = data;
break;
case 0x2000/4:
LOGMASKED(LOG_WRITES, "%s: DMA Memory Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Memory Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_mem_addr = data;
break;
case 0x2008/4:
LOGMASKED(LOG_WRITES, "%s: DMA Memory Address + Default Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Memory Address + Default Params Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_mem_addr = data;
break;
case 0x2010/4:
LOGMASKED(LOG_WRITES, "%s: DMA Line Count and Width Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Line Count and Width Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_size = data;
break;
case 0x2018/4:
LOGMASKED(LOG_WRITES, "%s: DMA Line Zoom and Stride Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Line Zoom and Stride Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_stride = data;
break;
case 0x2020/4:
LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA GIO64 Address Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_gio64_addr = data;
break;
case 0x2028/4:
LOGMASKED(LOG_WRITES, "%s: DMA GIO64 Address Write + Start DMA: %08x & %08x\n", machine().describe_context(), data, mem_mask);
{
LOGMASKED(LOG_WRITES | LOG_DMA, "%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;
if (m_dma_gio64_addr == 0x1f0f0a30)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
const uint32_t line_count = m_dma_size >> 16;
const uint32_t line_size = (uint16_t)m_dma_size;
const uint32_t line_stride = (uint16_t)m_dma_stride;
uint32_t src_addr = m_dma_mem_addr;
machine().debug_break();
for (uint32_t line = 0; line < line_count; line++)
{
for (uint32_t i = 0; i < line_size; i++)
{
space.write_dword(m_dma_gio64_addr, space.read_dword(dma_translate(src_addr)));
src_addr += 4;
}
src_addr += line_stride;
}
}
break;
}
case 0x2030/4:
LOGMASKED(LOG_WRITES, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Mode Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_mode = data;
break;
case 0x2038/4:
LOGMASKED(LOG_WRITES, "%s: DMA Zoom Count + Byte Count Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Zoom Count + Byte Count Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
m_dma_count = data;
break;
case 0x2040/4:
LOGMASKED(LOG_WRITES, "%s: DMA Start Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Start Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
// Start DMA
m_dma_running = 1;
break;
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);
LOGMASKED(LOG_WRITES | LOG_DMA, "%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;

View File

@ -43,6 +43,8 @@ protected:
static const device_timer_id TIMER_RPSS = 0;
private:
uint32_t dma_translate(uint32_t address);
required_device<cpu_device> m_maincpu;
required_device<eeprom_serial_93cxx_device> m_eeprom;
@ -71,14 +73,8 @@ private:
uint32_t m_gio64_substitute_bits;
uint32_t m_dma_int_cause;
uint32_t m_dma_control;
uint32_t m_dma_tlb_entry0_hi;
uint32_t m_dma_tlb_entry0_lo;
uint32_t m_dma_tlb_entry1_hi;
uint32_t m_dma_tlb_entry1_lo;
uint32_t m_dma_tlb_entry2_hi;
uint32_t m_dma_tlb_entry2_lo;
uint32_t m_dma_tlb_entry3_hi;
uint32_t m_dma_tlb_entry3_lo;
uint32_t m_dma_tlb_entry_hi[4];
uint32_t m_dma_tlb_entry_lo[4];
uint32_t m_rpss_counter;
uint32_t m_dma_mem_addr;
uint32_t m_dma_size;

View File

@ -39,7 +39,7 @@
#define LOG_COMMANDS (1 << 7)
#define LOG_ALL (LOG_UNKNOWN | LOG_VC2 | LOG_CMAP0 | LOG_CMAP1 | LOG_XMAP0 | LOG_XMAP1 | LOG_REX3)
#define VERBOSE (0)
#define VERBOSE (LOG_COMMANDS | LOG_UNKNOWN | LOG_REX3)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(NEWPORT_VIDEO, newport_video_device, "newport_video", "SGI Newport graphics board")
@ -59,7 +59,7 @@ newport_video_device::newport_video_device(const machine_config &mconfig, const
void newport_video_device::device_start()
{
m_base = make_unique_clear<uint32_t[]>((1280+64) * (1024+64));
m_base = make_unique_clear<uint8_t[]>((1280+64) * (1024+64));
save_pointer(NAME(m_base), (1280+64) * (1024+64));
save_item(NAME(m_vc2.m_vid_entry));
@ -167,7 +167,7 @@ void newport_video_device::device_start()
save_item(NAME(m_rex3.m_config));
save_item(NAME(m_rex3.m_status));
save_item(NAME(m_rex3.m_xfer_width));
save_item(NAME(m_rex3.m_skipline_kludge));
save_item(NAME(m_rex3.m_read_active));
save_item(NAME(m_cmap0.m_palette_idx));
save_item(NAME(m_cmap0.m_palette));
@ -188,7 +188,6 @@ void newport_video_device::device_reset()
m_rex3.m_draw_mode0 = 0x00000000;
m_rex3.m_draw_mode1 = 0x3002f001;
m_rex3.m_dcb_mode = 0x00000780;
m_rex3.m_skipline_kludge = 0;
m_xmap0.m_entries = 0x2;
m_xmap1.m_entries = 0x2;
@ -233,7 +232,7 @@ uint32_t newport_video_device::screen_update(screen_device &device, bitmap_rgb32
/* loop over rows and copy to the destination */
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
uint32_t *src = &m_base[1344 * y];
uint8_t *src = &m_base[1344 * y];
uint32_t *dest = &bitmap.pix32(y, cliprect.min_x);
/* loop over columns */
@ -244,7 +243,7 @@ uint32_t newport_video_device::screen_update(screen_device &device, bitmap_rgb32
{
cursor_pixel = get_cursor_pixel(x - ((int)m_vc2.m_cursor_x - 31), y - ((int)m_vc2.m_cursor_y - 31));
}
*dest++ = cursor_pixel ? cursor_pixel : *src;
*dest++ = cursor_pixel ? cursor_pixel : m_cmap0.m_palette[*src];
src++;
}
}
@ -869,6 +868,10 @@ READ32_MEMBER(newport_video_device::rex3_r)
return m_rex3.m_slope_red;
case 0x0230/4:
LOGMASKED(LOG_REX3, "REX3 Host Data Port MSW Read: %08x\n", m_rex3.m_host_dataport_msw);
if (m_rex3.m_read_active)
{
m_rex3.m_host_dataport_msw = do_pixel_read() << 24;
}
return m_rex3.m_host_dataport_msw;
case 0x0234/4:
LOGMASKED(LOG_REX3, "REX3 Host Data Port LSW Read: %08x\n", m_rex3.m_host_dataport_lsw);
@ -950,29 +953,233 @@ READ32_MEMBER(newport_video_device::rex3_r)
}
}
void newport_video_device::do_v_iline(int x1, int y1, int y2, uint8_t color, bool skip_last)
{
x1 += (m_rex3.m_xy_window >> 16) & 0x0fff;
y1 += m_rex3.m_xy_window & 0x0fff;
y2 += m_rex3.m_xy_window & 0x0fff;
int x = x1;
int y = y1;
int incy = (y2 < y1) ? -1 : 1;
if (skip_last)
y2 -= incy;
do
{
m_base[y * (1280 + 64) + x] = color;
y += incy;
} while (y != y2);
}
void newport_video_device::do_h_iline(int x1, int y1, int x2, uint8_t color, bool skip_last)
{
x1 += (m_rex3.m_xy_window >> 16) & 0x0fff;
x2 += (m_rex3.m_xy_window >> 16) & 0x0fff;
y1 += m_rex3.m_xy_window & 0x0fff;
int x = x1;
int y = y1;
if (skip_last)
x2--;
int addr = y * (1280 + 64) + x;
do
{
m_base[addr] = color;
addr++;
x++;
} while (x != x2);
}
void newport_video_device::do_iline(int x1, int y1, int x2, int y2, uint8_t color, bool skip_last)
{
x1 += (m_rex3.m_xy_window >> 16) & 0x0fff;
x2 += (m_rex3.m_xy_window >> 16) & 0x0fff;
y1 += m_rex3.m_xy_window & 0x0fff;
y2 += m_rex3.m_xy_window & 0x0fff;
unsigned char c1 = 0;
int incy = 1;
int dx;
if (x2 > x1)
dx = x2 - x1;
else
dx = x1 - x2;
int dy;
if (y2 > y1)
dy = y2 - y1;
else
dy = y1 - y2;
int t;
if (dy > dx)
{
t = y2;
y2 = x2;
x2 = t;
t = y1;
y1 = x1;
x1 = t;
t = dx;
dx = dy;
dy = t;
c1 = 1;
}
if (x1 > x2)
{
t = y2;
y2 = y1;
y1 = t;
t = x1;
x1 = x2;
x2 = t;
}
int horiz = dy << 1;
int diago = (dy - dx) << 1;
int e = (dy << 1) - dx;
if (y1 <= y2)
incy = 1;
else
incy = -1;
int x = x1;
int y = y1;
if (c1)
{
do
{
m_base[y * (1280 + 64) + x] = color;
if (e > 0)
{
y = y + incy;
e = e + diago;
}
else
{
e = e + horiz;
}
x++;
} while (skip_last ? x < x2 : x <= x2);
}
else
{
do
{
m_base[y * (1280 + 64) + x] = color;
if (e > 0)
{
y = y + incy;
e = e + diago;
}
else
{
e = e + horiz;
}
x++;
} while (skip_last ? x < x2 : x <= x2);
}
}
uint8_t newport_video_device::do_pixel_read()
{
uint8_t ret = 0;
uint16_t x = (uint16_t)(m_rex3.m_xy_start_i >> 16);
uint16_t y = (uint16_t)m_rex3.m_xy_start_i;
if (m_rex3.m_xy_start_i == m_rex3.m_xy_end_i)
m_rex3.m_read_active = false;
LOGMASKED(LOG_COMMANDS, "Reading from %04x, %04x\n", x, y);
m_rex3.m_bres_octant_inc1 = 0;
ret = m_base[y * (1280 + 64) + x];
x++;
if (x > (m_rex3.m_xy_end_i >> 16))
{
y++;
x = m_rex3.m_x_save;
}
m_rex3.m_xy_start_i = (x << 16) | y;
m_rex3.m_x_start_i = x;
m_rex3.m_x_start = ((m_rex3.m_xy_start_i & 0xffff0000) >> 5);
m_rex3.m_y_start = ((m_rex3.m_xy_start_i & 0x0000ffff) << 11);
return ret;
}
void newport_video_device::do_rex3_command()
{
uint32_t command = ((m_rex3.m_draw_mode0 & (1 << 15)) >> 15) |
((m_rex3.m_draw_mode0 & (1 << 5)) >> 4) |
((m_rex3.m_draw_mode0 & (1 << 9)) >> 7) |
((m_rex3.m_draw_mode0 & (1 << 8)) >> 5) |
((m_rex3.m_draw_mode0 & 0x0000001c) << 2) |
((m_rex3.m_draw_mode0 & 0x00000003) << 7);
static const char* const s_opcode_str[4] = { "Noop", "Read", "Draw", "Scr2Scr" };
static const char* const s_adrmode_str[8] = {
"Span", "Block", "IntLine", "FracLine", "AALine", "Unk5", "Unk6", "Unk7"
};
static const char* const s_planes_str[8] = {
"None", "RGB/CI", "RGBA", "Unk3", "OLAY", "PUP", "CID", "Unk7"
};
static const char* const s_drawdepth_str[4] = {
"4 bits", "8 bits", "12 bits", "24 bits"
};
static const char* const s_hostdepth_str[4] = {
"4 bits (1-2-1 BGR or 4 CI)", "8 bits (3-3-2 BGR or 8 CI)", "12 bits (4-4-4 BGR or 12 CI)", "32 bits (8-8-8-8 ABGR)"
};
static const char* const s_compare_str[8] = {
"Always", "src < dst", "src = dst", "src <= dst", "src > dst", "src != dst", "src >= dst", "Never"
};
static const char* const s_sfactor_str[8] = {
"0", "1", "dstc", "1-dstc", "srca", "1-srca", "Unk6", "Unk7"
};
static const char* const s_dfactor_str[8] = {
"0", "1", "srcc", "1-srcc", "srca", "1-srca", "Unk6", "Unk7"
};
static const char* const s_logicop_str[16] = {
"0", "src & dst", "src & !dst", "src", "!src & dst", "dst", "src ^ dst", "src | dst",
"!(src | dst)", "!(src ^ dst)", "!dst", "src | !dst", "!src", "!src | dst", "!(src & dst)", "1"
};
uint16_t start_x = (uint16_t)(m_rex3.m_xy_start_i >> 16);
uint16_t start_y = (uint16_t)m_rex3.m_xy_start_i;
uint16_t end_x = (uint16_t)(m_rex3.m_xy_end_i >> 16);
uint16_t end_y = (uint16_t)m_rex3.m_xy_end_i;
const uint32_t mode0 = m_rex3.m_draw_mode0;
const uint32_t mode1 = m_rex3.m_draw_mode1;
switch (command)
LOGMASKED(LOG_COMMANDS, "REX3 Command: %08x|%08x - %s %s:\n", mode0, mode1, s_opcode_str[mode0 & 3], s_adrmode_str[(mode0 >> 2) & 7]);
LOGMASKED(LOG_COMMANDS, " DoSetup:%d, ColorHost:%d, AlphaHost:%d, StopOnX:%d, StopOnY:%d\n", BIT(mode0, 5), BIT(mode0, 6), BIT(mode0, 7),
BIT(mode0, 8), BIT(mode0, 9));
LOGMASKED(LOG_COMMANDS, " SkipFirst:%d, SkipLast:%d, ZPattEn:%d, LSPattEn:%d, LSAdvLast:%d\n", BIT(mode0, 10), BIT(mode0, 11), BIT(mode0, 12),
BIT(mode0, 13), BIT(mode0, 14));
LOGMASKED(LOG_COMMANDS, " Length32:%d, ZOpaque:%d, LSOpaque:%d, Shade:%d, LROnly:%d\n", BIT(mode0, 15), BIT(mode0, 16), BIT(mode0, 17),
BIT(mode0, 18), BIT(mode0, 19));
LOGMASKED(LOG_COMMANDS, " XYOffset:%d, CIClamp:%d, EndFilter:%d, YStride:%d\n", BIT(mode0, 20), BIT(mode0, 21), BIT(mode0, 22), BIT(mode0, 23));
LOGMASKED(LOG_COMMANDS, " Planes:%s, DrawDepth:%s, DblSrc:%d\n", s_planes_str[mode1 & 7], s_drawdepth_str[(mode1 >> 3) & 3], BIT(mode1, 5));
LOGMASKED(LOG_COMMANDS, " GL YFlip:%d, RWPacked:%d, HostDepth:%s\n", BIT(mode1, 6), BIT(mode1, 7), s_hostdepth_str[(mode1 >> 8) & 3]);
LOGMASKED(LOG_COMMANDS, " RWDouble:%d, SwapEndian:%d, Compare:%s\n", BIT(mode1, 10), BIT(mode1, 11), s_compare_str[(mode1 >> 12) & 7]);
LOGMASKED(LOG_COMMANDS, " RGBMode:%d, Dither:%d, FastClear:%d, Blend:%d\n", BIT(mode1, 15), BIT(mode1, 16), BIT(mode1, 17), BIT(mode1, 18));
LOGMASKED(LOG_COMMANDS, " SrcFactor:%s, DstFactor:%s, BackBlend:%d, Prefetch:%d\n", s_sfactor_str[(mode1 >> 19) & 7], s_dfactor_str[(mode1 >> 22) & 7],
BIT(mode1, 25), BIT(mode1, 26));
LOGMASKED(LOG_COMMANDS, " BlendAlpha:%d, LogicOp:%s\n", BIT(mode1, 27), s_logicop_str[(mode1 >> 28) & 15]);
switch (mode0)
{
case 0x00000110:
case 0x00000006:
case 0x00000046:
{
uint16_t x = start_x;
uint16_t y = start_y;
LOGMASKED(LOG_COMMANDS, "Tux Logo Draw: %04x, %04x = %08x\n", x, y, m_cmap0.m_palette[m_rex3.m_host_dataport_msw >> 24]);
// m_rex3.m_skipline_kludge = 1;
LOGMASKED(LOG_COMMANDS, "%04x, %04x = %08x\n", x, y, m_cmap0.m_palette[m_rex3.m_host_dataport_msw >> 24]);
m_rex3.m_bres_octant_inc1 = 0;
m_base[y * (1280 + 64) + x] = m_cmap0.m_palette[m_rex3.m_host_dataport_msw >> 24];
m_base[y * (1280 + 64) + x] = m_rex3.m_host_dataport_msw;
x++;
if (x > (m_rex3.m_xy_end_i >> 16))
{
@ -985,40 +1192,47 @@ void newport_video_device::do_rex3_command()
m_rex3.m_y_start = ((m_rex3.m_xy_start_i & 0x0000ffff) << 11);
break;
}
case 0x0000011e:
LOGMASKED(LOG_COMMANDS, "Block draw: %04x, %04x to %04x, %04x = %08x\n", start_x, start_y, end_x, end_y, m_cmap0.m_palette[m_rex3.m_zero_fract]);
case 0x00000045:
{
m_rex3.m_read_active = true;
break;
}
case 0x00000102:
case 0x00000122:
{
uint32_t color = m_rex3.m_zero_fract & 0xff;
LOGMASKED(LOG_COMMANDS, "%04x, %04x to %04x, %04x = %08x\n", start_x, start_y, end_x, end_y, color);
for (uint16_t y = start_y; y <= end_y; y++)
{
for (uint16_t x = start_x; x <= end_x; x++)
{
m_base[y * (1280 + 64) + x] = m_cmap0.m_palette[m_rex3.m_zero_fract];
m_base[y * (1280 + 64) + x] = color;
}
}
break;
case 0x00000119:
if (!m_rex3.m_skipline_kludge)
}
case 0x00000326:
{
uint32_t color = m_rex3.m_zero_fract & 0xff;
if (BIT(mode1, 17))
{
LOGMASKED(LOG_COMMANDS, "Pattern Line Draw: %08x at %04x, %04x color %08x\n", m_rex3.m_z_pattern, m_rex3.m_xy_start_i >> 16, (uint16_t)m_rex3.m_xy_start_i, m_cmap0.m_palette[m_rex3.m_zero_fract]);
for (uint16_t x = start_x; x <= end_x && x < (start_x + 32); x++)
color = m_rex3.m_color_vram & 0xff;
}
LOGMASKED(LOG_COMMANDS, "%04x, %04x to %04x, %04x = %08x\n", start_x, start_y, end_x, end_y, m_cmap0.m_palette[m_rex3.m_zero_fract]);
for (uint16_t y = start_y; y <= end_y; y++)
{
for (uint16_t x = start_x; x <= end_x; x++)
{
if (m_rex3.m_z_pattern & (1 << (31 - (x - start_x))))
{
m_base[start_y * (1280 + 64) + x] = m_cmap0.m_palette[m_rex3.m_zero_fract];
}
m_base[y * (1280 + 64) + x] = color;
}
if (BIT(m_rex3.m_bres_octant_inc1, 24))
start_y--;
else
start_y++;
m_rex3.m_xy_start_i = (start_x << 16) | start_y;
m_rex3.m_y_start = ((m_rex3.m_xy_start_i & 0x0000ffff) << 11);
}
break;
case 0x0000019e:
}
case 0x00000327:
{
int16_t move_x = (int16_t)((m_rex3.m_xy_move >> 16) & 0x0000ffff);
int16_t move_y = (int16_t)m_rex3.m_xy_move;
LOGMASKED(LOG_COMMANDS, "FB to FB Copy: %04x, %04x - %04x, %04x to %04x, %04x\n", start_x, start_y, end_x, end_y, start_x + move_x, start_y + move_y);
LOGMASKED(LOG_COMMANDS, "%04x, %04x - %04x, %04x to %04x, %04x\n", start_x, start_y, end_x, end_y, start_x + move_x, start_y + move_y);
for (uint16_t y = start_y; y <= end_y; y++)
{
for (uint16_t x = start_x; x <= end_x; x++)
@ -1028,18 +1242,59 @@ void newport_video_device::do_rex3_command()
}
break;
}
case 0x0000032a:
case 0x00000b2a:
LOGMASKED(LOG_COMMANDS, "ILine: %04x, %04x to %04x, %04x = %08x\n", start_x, start_y, end_x, end_y, m_cmap0.m_palette[m_rex3.m_zero_fract]);
if (start_x == end_x)
{
do_v_iline(start_x, start_y, end_y, m_cmap0.m_palette[m_rex3.m_zero_fract], BIT(mode0, 11));
}
else if (start_y == end_y)
{
do_h_iline(start_x, start_y, end_x, m_cmap0.m_palette[m_rex3.m_zero_fract], BIT(mode0, 11));
}
else
{
do_iline(start_x, start_y, end_x, end_y, m_cmap0.m_palette[m_rex3.m_zero_fract], BIT(mode0, 11));
}
break;
case 0x00002106:
case 0x00009106:
case 0x00022106:
case 0x00029106:
{
const bool opaque = (mode0 == 0x00029106) || (mode0 == 0x00022106);
const uint32_t pattern = (mode0 == 0x00009106 || mode0 == 0x00029106) ? m_rex3.m_z_pattern : m_rex3.m_ls_pattern;
const uint8_t foreground = m_rex3.m_zero_fract & 0xff;
const uint8_t background = m_rex3.m_color_back & 0xff;
LOGMASKED(LOG_COMMANDS, "%08x at %04x, %04x color %08x\n", pattern, m_rex3.m_xy_start_i >> 16, (uint16_t)m_rex3.m_xy_start_i, foreground);
for (uint16_t x = start_x; x <= end_x && x < (start_x + 32); x++)
{
if (pattern & (1 << (31 - (x - start_x))))
{
m_base[start_y * (1280 + 64) + x] = foreground;
}
else if (opaque)
{
m_base[start_y * (1280 + 64) + x] = background;
}
}
if (BIT(m_rex3.m_bres_octant_inc1, 24))
start_y--;
else
start_y++;
m_rex3.m_xy_start_i = (start_x << 16) | start_y;
m_rex3.m_y_start = ((m_rex3.m_xy_start_i & 0x0000ffff) << 11);
break;
}
default:
LOGMASKED(LOG_COMMANDS | LOG_UNKNOWN, "Unknown draw command: %08x\n", command);
LOGMASKED(LOG_COMMANDS | LOG_UNKNOWN, "Draw command %08x not recognized\n", m_rex3.m_draw_mode0);
break;
}
}
WRITE32_MEMBER(newport_video_device::rex3_w)
{
if (offset & 0x00000200)
{
LOGMASKED(LOG_REX3 | LOG_COMMANDS, "Start Command\n");
}
switch (offset & ~(0x800/4))
{
case 0x0000/4:
@ -1288,10 +1543,6 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
case 0x0014/4:
LOGMASKED(LOG_REX3, "REX3 Pattern Register Write: %08x\n", data);
m_rex3.m_z_pattern = data;
if (offset & 0x00000200)
{
do_rex3_command();
}
break;
case 0x0018/4:
LOGMASKED(LOG_REX3, "REX3 Opaque Pattern / Blendfunc Dest Color Write: %08x\n", data);
@ -1356,10 +1607,6 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
case 0x0114/4:
LOGMASKED(LOG_REX3, "REX3 XYMove Write: %08x\n", data);
m_rex3.m_xy_move = data;
if (offset & 0x00000200)
{
do_rex3_command();
}
break;
case 0x0118/4:
LOGMASKED(LOG_REX3, "REX3 Bresenham D Write: %08x\n", data);
@ -1432,10 +1679,6 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
m_rex3.m_xy_end_i = data;
m_rex3.m_x_end = ((m_rex3.m_xy_end_i & 0xffff0000) >> 5);
m_rex3.m_y_end = ((m_rex3.m_xy_end_i & 0x0000ffff) << 11);
if (offset & 0x00000200)
{
do_rex3_command();
}
break;
case 0x0158/4:
LOGMASKED(LOG_REX3, "REX3 XStartEnd (integer) Write: %08x\n", data);
@ -1549,10 +1792,6 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
case 0x0230/4:
//verboselog(machine(), 3, "REX3 Host Data Port MSW Write: %08x\n", data );
m_rex3.m_host_dataport_msw = data;
if (offset & 0x00000200)
{
do_rex3_command();
}
break;
case 0x0234/4:
LOGMASKED(LOG_REX3, "REX3 Host Data Port LSW Write: %08x\n", data);
@ -1678,4 +1917,9 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
LOGMASKED(LOG_REX3 | LOG_UNKNOWN, "Unknown REX3 Write: %08x (%08x): %08x\n", 0xbf0f0000 + (offset << 2), mem_mask, data);
break;
}
if (offset & 0x00000200)
{
do_rex3_command();
}
}

View File

@ -157,10 +157,9 @@ private:
uint32_t m_config;
uint32_t m_status;
uint8_t m_xfer_width;
uint32_t m_skipline_kludge;
bool m_read_active;
};
struct cmap_t
{
uint16_t m_palette_idx;
@ -180,6 +179,11 @@ private:
DECLARE_WRITE32_MEMBER(xmap1_w);
DECLARE_READ32_MEMBER(vc2_r);
DECLARE_WRITE32_MEMBER(vc2_w);
void do_v_iline(int x1, int y1, int y2, uint8_t color, bool skip_last);
void do_h_iline(int x1, int y1, int x2, uint8_t color, bool skip_last);
void do_iline(int x1, int y1, int x2, int y2, uint8_t color, bool skip_last);
uint8_t do_pixel_read();
void do_rex3_command();
required_device<cpu_device> m_maincpu;
@ -188,7 +192,7 @@ private:
xmap_t m_xmap0;
xmap_t m_xmap1;
rex3_t m_rex3;
std::unique_ptr<uint32_t[]> m_base;
std::unique_ptr<uint8_t[]> m_base;
cmap_t m_cmap0;
};