mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
-sgi_mc_device: Basic VDMA support, address translation is currently broken. [Ryan Holtz]
-newport: Various changes, nw
This commit is contained in:
parent
8ed8f42a30
commit
ea6d72aa5e
@ -32,6 +32,7 @@ sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, dev
|
||||
, m_maincpu(*this, finder_base::DUMMY_TAG)
|
||||
, m_eeprom(*this, finder_base::DUMMY_TAG)
|
||||
, m_rpss_timer(nullptr)
|
||||
, m_dma_timer(nullptr)
|
||||
, m_watchdog(0)
|
||||
, m_sys_id(0)
|
||||
, m_rpss_divider(0)
|
||||
@ -60,7 +61,7 @@ sgi_mc_device::sgi_mc_device(const machine_config &mconfig, const char *tag, dev
|
||||
, m_dma_gio64_addr(0)
|
||||
, m_dma_mode(0)
|
||||
, m_dma_count(0)
|
||||
, m_dma_running(0)
|
||||
, m_dma_run(0)
|
||||
, m_eeprom_ctrl(0)
|
||||
, m_rpss_divide_counter(0)
|
||||
, m_rpss_divide_count(0)
|
||||
@ -87,6 +88,9 @@ void sgi_mc_device::device_start()
|
||||
m_rpss_timer = timer_alloc(TIMER_RPSS);
|
||||
m_rpss_timer->adjust(attotime::never);
|
||||
|
||||
m_dma_timer = timer_alloc(TIMER_DMA);
|
||||
m_dma_timer->adjust(attotime::never);
|
||||
|
||||
save_item(NAME(m_cpu_control));
|
||||
save_item(NAME(m_watchdog));
|
||||
save_item(NAME(m_sys_id));
|
||||
@ -119,7 +123,7 @@ void sgi_mc_device::device_start()
|
||||
save_item(NAME(m_dma_gio64_addr));
|
||||
save_item(NAME(m_dma_mode));
|
||||
save_item(NAME(m_dma_count));
|
||||
save_item(NAME(m_dma_running));
|
||||
save_item(NAME(m_dma_run));
|
||||
save_item(NAME(m_eeprom_ctrl));
|
||||
save_item(NAME(m_semaphore));
|
||||
save_item(NAME(m_rpss_divide_counter));
|
||||
@ -165,13 +169,15 @@ void sgi_mc_device::device_reset()
|
||||
m_dma_gio64_addr = 0;
|
||||
m_dma_mode = 0;
|
||||
m_dma_count = 0;
|
||||
m_dma_running = 0;
|
||||
m_dma_run = 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_divide_counter = 4;
|
||||
m_rpss_divide_count = 4;
|
||||
m_rpss_increment = 1;
|
||||
|
||||
m_space = &m_maincpu->space(AS_PROGRAM);
|
||||
}
|
||||
|
||||
void sgi_mc_device::set_cpu_buserr(uint32_t address)
|
||||
@ -191,12 +197,91 @@ uint32_t sgi_mc_device::dma_translate(uint32_t address)
|
||||
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 ((m_dma_tlb_entry_lo[entry] &~ 0x3f) << 6) + (offset & 0xfff);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sgi_mc_device::dma_tick()
|
||||
{
|
||||
uint32_t addr = m_dma_mem_addr;
|
||||
if (m_dma_control & (1 << 8))
|
||||
{ // Enable virtual address translation
|
||||
addr = dma_translate(addr);
|
||||
}
|
||||
|
||||
if (m_dma_mode & (1 << 1))
|
||||
{ // Graphics to host
|
||||
if (m_dma_mode & (1 << 3))
|
||||
{ // Fill mode
|
||||
m_space->write_dword(addr, m_dma_gio64_addr);
|
||||
m_dma_count -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_space->write_byte(addr, m_space->read_byte(m_dma_gio64_addr));
|
||||
m_dma_mem_addr++;
|
||||
m_dma_count--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Host to graphics
|
||||
const uint32_t remaining = m_dma_count & 0x0000ffff;
|
||||
uint32_t length = 4;
|
||||
uint32_t shift = 24;
|
||||
if (remaining < 4)
|
||||
length = remaining;
|
||||
|
||||
uint32_t data = 0;
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
data |= m_space->read_byte(addr) << shift;
|
||||
addr++;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
m_space->write_byte(m_dma_gio64_addr, data);
|
||||
m_dma_mem_addr += length;
|
||||
m_dma_count -= length;
|
||||
}
|
||||
|
||||
if ((m_dma_count & 0x0000ffff) == 0)
|
||||
{ // If remaining byte count is 0, deduct zoom count
|
||||
if (!BIT(m_dma_mode, 3))
|
||||
logerror("Remaining DMA byte count is 0, count register contains %08x, deducting a zoom line\n", m_dma_count);
|
||||
m_dma_count -= 0x00010000;
|
||||
if (m_dma_count == 0)
|
||||
{ // If remaining zoom count is also 0, move to next line
|
||||
m_dma_mem_addr += m_dma_stride & 0x0000ffff;
|
||||
m_dma_size -= 0x00010000;
|
||||
if (!BIT(m_dma_mode, 3))
|
||||
logerror("Remaining DMA zoom count is also 0, deducting a line, DMA size now %08x\n", m_dma_size);
|
||||
if ((m_dma_size & 0xffff0000) == 0)
|
||||
{ // If no remaining lines, DMA is done.
|
||||
if (!BIT(m_dma_mode, 3))
|
||||
logerror("No remaining lines, DMA is done\n");
|
||||
m_dma_timer->adjust(attotime::never);
|
||||
m_dma_run |= (1 << 3);
|
||||
m_dma_run &= ~(1 << 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dma_count = (m_dma_stride & 0x03ff0000) | (m_dma_size & 0x0000ffff);
|
||||
if (!BIT(m_dma_mode, 3))
|
||||
logerror("Reloading DMA count with %08x\n", m_dma_count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // If remaining zoom count is non-zero, reload byte count and return source address to the beginning of the line.
|
||||
m_dma_count |= m_dma_size & 0x0000ffff;
|
||||
m_dma_mem_addr -= m_dma_size & 0x0000ffff;
|
||||
if (!BIT(m_dma_mode, 3))
|
||||
logerror("Remaining DMA zoom count is non-zero, returning source address to beginning, DMA count now %08x\n", m_dma_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(sgi_mc_device::read)
|
||||
{
|
||||
switch (offset & ~1)
|
||||
@ -336,16 +421,13 @@ READ32_MEMBER(sgi_mc_device::read)
|
||||
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Start Read\n", machine().describe_context());
|
||||
return 0;
|
||||
case 0x2048/4:
|
||||
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)
|
||||
{
|
||||
if (!(m_dma_run & 0x40))
|
||||
{
|
||||
m_dma_running = 0;
|
||||
return 0x00000040;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
LOGMASKED(LOG_READS | LOG_DMA, "%s: DMA Run Read: %08x & %08x\n", machine().describe_context(), m_dma_run, mem_mask);
|
||||
}
|
||||
return m_dma_run;
|
||||
}
|
||||
case 0x10000/4:
|
||||
case 0x11000/4:
|
||||
case 0x12000/4:
|
||||
@ -532,10 +614,14 @@ WRITE32_MEMBER( sgi_mc_device::write )
|
||||
break;
|
||||
case 0x2010/4:
|
||||
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Line Count and Width Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_dma_count &= 0xffff0000;
|
||||
m_dma_count |= data & 0x0000ffff;
|
||||
m_dma_size = data;
|
||||
break;
|
||||
case 0x2018/4:
|
||||
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Line Zoom and Stride Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
m_dma_count &= 0x0000ffff;
|
||||
m_dma_count |= data & 0x03ff0000;
|
||||
m_dma_stride = data;
|
||||
break;
|
||||
case 0x2020/4:
|
||||
@ -546,25 +632,8 @@ WRITE32_MEMBER( sgi_mc_device::write )
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
m_dma_run |= 0x40;
|
||||
m_dma_timer->adjust(attotime::from_hz(33333333), 0, attotime::from_hz(33333333));
|
||||
break;
|
||||
}
|
||||
case 0x2030/4:
|
||||
@ -577,14 +646,18 @@ WRITE32_MEMBER( sgi_mc_device::write )
|
||||
break;
|
||||
case 0x2040/4:
|
||||
LOGMASKED(LOG_WRITES | LOG_DMA, "%s: DMA Start Write: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
// Start DMA
|
||||
m_dma_running = 1;
|
||||
m_dma_run |= 0x40;
|
||||
m_dma_timer->adjust(attotime::from_hz(33333333), 0, attotime::from_hz(33333333));
|
||||
break;
|
||||
case 0x2070/4:
|
||||
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;
|
||||
m_dma_size = 0x0001000c;
|
||||
m_dma_stride = 0x00010000;
|
||||
m_dma_count = 0x0001000c;
|
||||
m_dma_mode = 0x00000028;
|
||||
m_dma_run |= 0x40;
|
||||
m_dma_timer->adjust(attotime::from_hz(33333333), 0, attotime::from_hz(33333333));
|
||||
break;
|
||||
case 0x10000/4:
|
||||
case 0x11000/4:
|
||||
@ -625,4 +698,8 @@ void sgi_mc_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
m_rpss_counter += m_rpss_increment;
|
||||
}
|
||||
}
|
||||
else if (id == TIMER_DMA)
|
||||
{
|
||||
dma_tick();
|
||||
}
|
||||
}
|
||||
|
@ -41,14 +41,19 @@ protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
static const device_timer_id TIMER_RPSS = 0;
|
||||
static const device_timer_id TIMER_DMA = 1;
|
||||
|
||||
private:
|
||||
uint32_t dma_translate(uint32_t address);
|
||||
void dma_tick();
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||
|
||||
address_space *m_space;
|
||||
|
||||
emu_timer *m_rpss_timer;
|
||||
emu_timer *m_dma_timer;
|
||||
|
||||
uint32_t m_cpu_control[2];
|
||||
uint32_t m_watchdog;
|
||||
@ -82,7 +87,7 @@ private:
|
||||
uint32_t m_dma_gio64_addr;
|
||||
uint32_t m_dma_mode;
|
||||
uint32_t m_dma_count;
|
||||
uint32_t m_dma_running;
|
||||
uint32_t m_dma_run;
|
||||
uint32_t m_eeprom_ctrl;
|
||||
uint32_t m_semaphore[16];
|
||||
int m_rpss_divide_counter;
|
||||
|
@ -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 (LOG_COMMANDS | LOG_UNKNOWN | LOG_REX3)
|
||||
#define VERBOSE (LOG_COMMANDS | LOG_UNKNOWN | LOG_REX3 | LOG_CMAP0 | LOG_CMAP1)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(NEWPORT_VIDEO, newport_video_device, "newport_video", "SGI Newport graphics board")
|
||||
@ -108,8 +108,8 @@ void newport_video_device::device_start()
|
||||
save_item(NAME(m_rex3.m_color_back));
|
||||
save_item(NAME(m_rex3.m_color_vram));
|
||||
save_item(NAME(m_rex3.m_alpha_ref));
|
||||
save_item(NAME(m_rex3.m_smask0_x));
|
||||
save_item(NAME(m_rex3.m_smask0_y));
|
||||
save_item(NAME(m_rex3.m_smask_x));
|
||||
save_item(NAME(m_rex3.m_smask_y));
|
||||
save_item(NAME(m_rex3.m_setup));
|
||||
save_item(NAME(m_rex3.m_step_z));
|
||||
save_item(NAME(m_rex3.m_x_start));
|
||||
@ -153,14 +153,6 @@ void newport_video_device::device_start()
|
||||
save_item(NAME(m_rex3.m_dcb_slave_select));
|
||||
save_item(NAME(m_rex3.m_dcb_data_msw));
|
||||
save_item(NAME(m_rex3.m_dcb_data_lsw));
|
||||
save_item(NAME(m_rex3.m_s_mask1_x));
|
||||
save_item(NAME(m_rex3.m_s_mask1_y));
|
||||
save_item(NAME(m_rex3.m_s_mask2_x));
|
||||
save_item(NAME(m_rex3.m_s_mask2_y));
|
||||
save_item(NAME(m_rex3.m_s_mask3_x));
|
||||
save_item(NAME(m_rex3.m_s_mask3_y));
|
||||
save_item(NAME(m_rex3.m_s_mask4_x));
|
||||
save_item(NAME(m_rex3.m_s_mask4_y));
|
||||
save_item(NAME(m_rex3.m_top_scanline));
|
||||
save_item(NAME(m_rex3.m_xy_window));
|
||||
save_item(NAME(m_rex3.m_clip_mode));
|
||||
@ -260,7 +252,7 @@ WRITE32_MEMBER(newport_video_device::cmap0_w)
|
||||
m_cmap0.m_palette_idx = (uint16_t)data;
|
||||
break;
|
||||
case 0x02:
|
||||
m_cmap0.m_palette[m_cmap0.m_palette_idx] = data >> 8;
|
||||
m_cmap0.m_palette[m_cmap0.m_palette_idx & 0xff] = data >> 8;
|
||||
LOGMASKED(LOG_CMAP0, "CMAP0 Palette Entry %04x Write: %08x\n", m_cmap0.m_palette_idx, data >> 8);
|
||||
break;
|
||||
default:
|
||||
@ -716,6 +708,10 @@ WRITE_LINE_MEMBER(newport_video_device::vblank_w)
|
||||
if (BIT(m_vc2.m_display_ctrl, 0))
|
||||
m_hpc3->raise_local_irq(1, ioc2_device::INT3_LOCAL1_RETRACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rex3.m_status &= ~0x20;
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(newport_video_device::rex3_r)
|
||||
@ -750,11 +746,11 @@ READ32_MEMBER(newport_video_device::rex3_r)
|
||||
LOGMASKED(LOG_REX3, "REX3 AFUNCTION Reference Alpha Read: %08x\n", m_rex3.m_alpha_ref);
|
||||
return m_rex3.m_alpha_ref;
|
||||
case 0x0028/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 0 X Min/Max Read: %08x\n", m_rex3.m_smask0_x);
|
||||
return m_rex3.m_smask0_x;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 0 X Min/Max Read: %08x\n", m_rex3.m_smask_x[0]);
|
||||
return m_rex3.m_smask_x[0];
|
||||
case 0x002c/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 0 Y Min/Max Read: %08x\n", m_rex3.m_smask0_y);
|
||||
return m_rex3.m_smask0_y;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 0 Y Min/Max Read: %08x\n", m_rex3.m_smask_y[0]);
|
||||
return m_rex3.m_smask_y[0];
|
||||
case 0x0030/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Line/Span Setup Read: %08x\n", m_rex3.m_setup);
|
||||
return m_rex3.m_setup;
|
||||
@ -867,11 +863,11 @@ READ32_MEMBER(newport_video_device::rex3_r)
|
||||
LOGMASKED(LOG_REX3, "REX3 Red/CI Slope (copy) Read: %08x\n", m_rex3.m_slope_red);
|
||||
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;
|
||||
m_rex3.m_host_dataport_msw = do_pixel_word_read();
|
||||
}
|
||||
LOGMASKED(LOG_REX3, "REX3 Host Data Port MSW Read: %08x\n", m_rex3.m_host_dataport_msw);
|
||||
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);
|
||||
@ -901,29 +897,29 @@ READ32_MEMBER(newport_video_device::rex3_r)
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data LSW Read: %08x\n", m_rex3.m_dcb_data_lsw);
|
||||
return m_rex3.m_dcb_data_lsw;
|
||||
case 0x1300/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 1 X Min/Max Read: %08x\n", m_rex3.m_s_mask1_x);
|
||||
return m_rex3.m_s_mask1_x;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 1 X Min/Max Read: %08x\n", m_rex3.m_smask_x[1]);
|
||||
return m_rex3.m_smask_x[1];
|
||||
case 0x1304/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 1 Y Min/Max Read: %08x\n", m_rex3.m_s_mask1_y);
|
||||
return m_rex3.m_s_mask1_y;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 1 Y Min/Max Read: %08x\n", m_rex3.m_smask_y[1]);
|
||||
return m_rex3.m_smask_y[1];
|
||||
case 0x1308/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 2 X Min/Max Read: %08x\n", m_rex3.m_s_mask2_x);
|
||||
return m_rex3.m_s_mask2_x;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 2 X Min/Max Read: %08x\n", m_rex3.m_smask_x[2]);
|
||||
return m_rex3.m_smask_x[2];
|
||||
case 0x130c/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 2 Y Min/Max Read: %08x\n", m_rex3.m_s_mask2_y);
|
||||
return m_rex3.m_s_mask2_y;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 2 Y Min/Max Read: %08x\n", m_rex3.m_smask_y[2]);
|
||||
return m_rex3.m_smask_y[2];
|
||||
case 0x1310/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 3 X Min/Max Read: %08x\n", m_rex3.m_s_mask3_x);
|
||||
return m_rex3.m_s_mask3_x;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 3 X Min/Max Read: %08x\n", m_rex3.m_smask_x[3]);
|
||||
return m_rex3.m_smask_x[3];
|
||||
case 0x1314/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 3 Y Min/Max Read: %08x\n", m_rex3.m_s_mask3_y);
|
||||
return m_rex3.m_s_mask3_y;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 3 Y Min/Max Read: %08x\n", m_rex3.m_smask_y[3]);
|
||||
return m_rex3.m_smask_y[3];
|
||||
case 0x1318/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 4 X Min/Max Read: %08x\n", m_rex3.m_s_mask4_x);
|
||||
return m_rex3.m_s_mask4_x;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 4 X Min/Max Read: %08x\n", m_rex3.m_smask_x[4]);
|
||||
return m_rex3.m_smask_x[4];
|
||||
case 0x131c/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 4 Y Min/Max Read: %08x\n", m_rex3.m_s_mask4_y);
|
||||
return m_rex3.m_s_mask4_y;
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 4 Y Min/Max Read: %08x\n", m_rex3.m_smask_y[4]);
|
||||
return m_rex3.m_smask_y[4];
|
||||
case 0x1320/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Top of Screen Scanline Read: %08x\n", m_rex3.m_top_scanline);
|
||||
return m_rex3.m_top_scanline;
|
||||
@ -953,6 +949,32 @@ READ32_MEMBER(newport_video_device::rex3_r)
|
||||
}
|
||||
}
|
||||
|
||||
void newport_video_device::write_pixel(uint32_t x, uint32_t y, uint8_t color)
|
||||
{
|
||||
if (m_rex3.m_clip_mode & 0x1f)
|
||||
{
|
||||
for (uint8_t bit = 0; bit < 5; bit++)
|
||||
{
|
||||
if (!BIT(m_rex3.m_clip_mode, bit))
|
||||
continue;
|
||||
if (x < ((m_rex3.m_smask_x[bit] >> 16) & 0x0fff))
|
||||
return;
|
||||
if (x > (m_rex3.m_smask_x[bit] & 0x0fff))
|
||||
return;
|
||||
if (y < ((m_rex3.m_smask_y[bit] >> 16) & 0x0fff))
|
||||
return;
|
||||
if (y > (m_rex3.m_smask_y[bit] & 0x0fff))
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (x > 1280 || y > 1024)
|
||||
{
|
||||
logerror("Warning: Attempting to write pixel to %d,%d - rejecting\n", x, y);
|
||||
return;
|
||||
}
|
||||
m_base[y * (1280 + 64) + x] = color;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -967,7 +989,7 @@ void newport_video_device::do_v_iline(int x1, int y1, int y2, uint8_t color, boo
|
||||
|
||||
do
|
||||
{
|
||||
m_base[y * (1280 + 64) + x] = color;
|
||||
write_pixel(x, y, color);
|
||||
y += incy;
|
||||
} while (y != y2);
|
||||
}
|
||||
@ -987,7 +1009,7 @@ void newport_video_device::do_h_iline(int x1, int y1, int x2, uint8_t color, boo
|
||||
int addr = y * (1280 + 64) + x;
|
||||
do
|
||||
{
|
||||
m_base[addr] = color;
|
||||
write_pixel(x, y, color);
|
||||
addr++;
|
||||
x++;
|
||||
} while (x != x2);
|
||||
@ -1060,7 +1082,7 @@ void newport_video_device::do_iline(int x1, int y1, int x2, int y2, uint8_t colo
|
||||
{
|
||||
do
|
||||
{
|
||||
m_base[y * (1280 + 64) + x] = color;
|
||||
write_pixel(x, y, color);
|
||||
|
||||
if (e > 0)
|
||||
{
|
||||
@ -1079,7 +1101,7 @@ void newport_video_device::do_iline(int x1, int y1, int x2, int y2, uint8_t colo
|
||||
{
|
||||
do
|
||||
{
|
||||
m_base[y * (1280 + 64) + x] = color;
|
||||
write_pixel(x, y, color);
|
||||
|
||||
if (e > 0)
|
||||
{
|
||||
@ -1098,14 +1120,13 @@ void newport_video_device::do_iline(int x1, int y1, int x2, int y2, uint8_t colo
|
||||
|
||||
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];
|
||||
const uint8_t ret = m_base[y * (1280 + 64) + x];
|
||||
x++;
|
||||
if (x > (m_rex3.m_xy_end_i >> 16))
|
||||
{
|
||||
@ -1119,6 +1140,23 @@ uint8_t newport_video_device::do_pixel_read()
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t newport_video_device::do_pixel_word_read()
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
uint16_t x_start = (uint16_t)(m_rex3.m_xy_start_i >> 16);
|
||||
uint16_t x_end = (uint16_t)(m_rex3.m_xy_end_i >> 16);
|
||||
uint16_t width = (x_end - x_start) + 1;
|
||||
if (width > 4)
|
||||
width = 4;
|
||||
uint32_t shift = 24;
|
||||
for (uint16_t i = 0; i < width; i++)
|
||||
{
|
||||
ret |= do_pixel_read() << shift;
|
||||
shift -= 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void newport_video_device::do_rex3_command()
|
||||
{
|
||||
static const char* const s_opcode_str[4] = { "Noop", "Read", "Draw", "Scr2Scr" };
|
||||
@ -1173,13 +1211,12 @@ void newport_video_device::do_rex3_command()
|
||||
switch (mode0)
|
||||
{
|
||||
case 0x00000006:
|
||||
case 0x00000046:
|
||||
{
|
||||
uint16_t x = start_x;
|
||||
uint16_t y = start_y;
|
||||
LOGMASKED(LOG_COMMANDS, "%04x, %04x = %08x\n", x, y, m_cmap0.m_palette[m_rex3.m_host_dataport_msw >> 24]);
|
||||
LOGMASKED(LOG_COMMANDS, "%04x, %04x = %02x\n", x, y, m_rex3.m_zero_fract & 0xff);
|
||||
m_rex3.m_bres_octant_inc1 = 0;
|
||||
m_base[y * (1280 + 64) + x] = m_rex3.m_host_dataport_msw;
|
||||
write_pixel(x, y, m_rex3.m_zero_fract & 0xff);
|
||||
x++;
|
||||
if (x > (m_rex3.m_xy_end_i >> 16))
|
||||
{
|
||||
@ -1192,6 +1229,43 @@ void newport_video_device::do_rex3_command()
|
||||
m_rex3.m_y_start = ((m_rex3.m_xy_start_i & 0x0000ffff) << 11);
|
||||
break;
|
||||
}
|
||||
case 0x00000046: // Block Draw, Host
|
||||
{
|
||||
uint16_t x = start_x;
|
||||
uint16_t y = start_y;
|
||||
m_rex3.m_bres_octant_inc1 = 0;
|
||||
uint16_t length;
|
||||
if (BIT(mode1, 7)) // Packed
|
||||
{
|
||||
uint16_t remaining_length = ((m_rex3.m_xy_end_i >> 16) - start_x) + 1;
|
||||
length = 4;
|
||||
if (remaining_length < length)
|
||||
length = remaining_length;
|
||||
LOGMASKED(LOG_COMMANDS, "%04x, %04x = %08x\n", x, y, m_rex3.m_host_dataport_msw);
|
||||
for (uint16_t i = 0; i < length; i++)
|
||||
{
|
||||
write_pixel(x + i, y, m_rex3.m_host_dataport_msw >> 24);
|
||||
m_rex3.m_host_dataport_msw <<= 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = 1;
|
||||
LOGMASKED(LOG_COMMANDS, "%04x, %04x = %02x\n", x, y, m_rex3.m_host_dataport_msw >> 24);
|
||||
write_pixel(x, y, m_rex3.m_host_dataport_msw >> 24);
|
||||
}
|
||||
x += length;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case 0x00000045:
|
||||
{
|
||||
m_rex3.m_read_active = true;
|
||||
@ -1206,7 +1280,7 @@ void newport_video_device::do_rex3_command()
|
||||
{
|
||||
for (uint16_t x = start_x; x <= end_x; x++)
|
||||
{
|
||||
m_base[y * (1280 + 64) + x] = color;
|
||||
write_pixel(x, y, color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1223,7 +1297,7 @@ void newport_video_device::do_rex3_command()
|
||||
{
|
||||
for (uint16_t x = start_x; x <= end_x; x++)
|
||||
{
|
||||
m_base[y * (1280 + 64) + x] = color;
|
||||
write_pixel(x, y, color);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1237,7 +1311,7 @@ void newport_video_device::do_rex3_command()
|
||||
{
|
||||
for (uint16_t x = start_x; x <= end_x; x++)
|
||||
{
|
||||
m_base[(y + move_y) * (1280 + 64) + (x + move_x)] = m_base[y * (1280 + 64) + x];
|
||||
write_pixel(x + move_x, y + move_y, m_base[y * (1280 + 64) + x]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1272,11 +1346,11 @@ void newport_video_device::do_rex3_command()
|
||||
{
|
||||
if (pattern & (1 << (31 - (x - start_x))))
|
||||
{
|
||||
m_base[start_y * (1280 + 64) + x] = foreground;
|
||||
write_pixel(x, start_y, foreground);
|
||||
}
|
||||
else if (opaque)
|
||||
{
|
||||
m_base[start_y * (1280 + 64) + x] = background;
|
||||
write_pixel(x, start_y, background);
|
||||
}
|
||||
}
|
||||
if (BIT(m_rex3.m_bres_octant_inc1, 24))
|
||||
@ -1561,11 +1635,11 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
|
||||
break;
|
||||
case 0x0028/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 0 X Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_smask0_x = data;
|
||||
m_rex3.m_smask_x[0] = data;
|
||||
break;
|
||||
case 0x002c/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 0 Y Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_smask0_y = data;
|
||||
m_rex3.m_smask_y[0] = data;
|
||||
break;
|
||||
case 0x0030/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Line/Span Setup Write: %08x\n", data);
|
||||
@ -1790,7 +1864,7 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
|
||||
m_rex3.m_slope_red = data;
|
||||
break;
|
||||
case 0x0230/4:
|
||||
//verboselog(machine(), 3, "REX3 Host Data Port MSW Write: %08x\n", data );
|
||||
LOGMASKED(LOG_REX3, "REX3 Host Data Port MSW Write: %08x\n", data);
|
||||
m_rex3.m_host_dataport_msw = data;
|
||||
break;
|
||||
case 0x0234/4:
|
||||
@ -1861,35 +1935,35 @@ WRITE32_MEMBER(newport_video_device::rex3_w)
|
||||
break;
|
||||
case 0x1300/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 1 X Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask1_x = data;
|
||||
m_rex3.m_smask_x[1] = data;
|
||||
break;
|
||||
case 0x1304/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 1 Y Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask1_y = data;
|
||||
m_rex3.m_smask_y[1] = data;
|
||||
break;
|
||||
case 0x1308/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 2 X Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask2_x = data;
|
||||
m_rex3.m_smask_x[2] = data;
|
||||
break;
|
||||
case 0x130c/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 2 Y Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask2_y = data;
|
||||
m_rex3.m_smask_y[2] = data;
|
||||
break;
|
||||
case 0x1310/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 3 X Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask3_x = data;
|
||||
m_rex3.m_smask_x[3] = data;
|
||||
break;
|
||||
case 0x1314/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 3 Y Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask3_y = data;
|
||||
m_rex3.m_smask_y[3] = data;
|
||||
break;
|
||||
case 0x1318/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 4 X Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask4_x = data;
|
||||
m_rex3.m_smask_x[4] = data;
|
||||
break;
|
||||
case 0x131c/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Screenmask 4 Y Min/Max Write: %08x\n", data);
|
||||
m_rex3.m_s_mask4_y = data;
|
||||
m_rex3.m_smask_y[4] = data;
|
||||
break;
|
||||
case 0x1320/4:
|
||||
LOGMASKED(LOG_REX3, "REX3 Top of Screen Scanline Write: %08x\n", data);
|
||||
|
@ -99,8 +99,6 @@ private:
|
||||
uint32_t m_color_back;
|
||||
uint32_t m_color_vram;
|
||||
uint32_t m_alpha_ref;
|
||||
uint32_t m_smask0_x;
|
||||
uint32_t m_smask0_y;
|
||||
uint32_t m_setup;
|
||||
uint32_t m_step_z;
|
||||
uint32_t m_x_start;
|
||||
@ -143,14 +141,8 @@ private:
|
||||
uint32_t m_dcb_slave_select;
|
||||
uint32_t m_dcb_data_msw;
|
||||
uint32_t m_dcb_data_lsw;
|
||||
uint32_t m_s_mask1_x;
|
||||
uint32_t m_s_mask1_y;
|
||||
uint32_t m_s_mask2_x;
|
||||
uint32_t m_s_mask2_y;
|
||||
uint32_t m_s_mask3_x;
|
||||
uint32_t m_s_mask3_y;
|
||||
uint32_t m_s_mask4_x;
|
||||
uint32_t m_s_mask4_y;
|
||||
uint32_t m_smask_x[5];
|
||||
uint32_t m_smask_y[5];
|
||||
uint32_t m_top_scanline;
|
||||
uint32_t m_xy_window;
|
||||
uint32_t m_clip_mode;
|
||||
@ -180,10 +172,12 @@ private:
|
||||
DECLARE_READ32_MEMBER(vc2_r);
|
||||
DECLARE_WRITE32_MEMBER(vc2_w);
|
||||
|
||||
void write_pixel(uint32_t x, uint32_t y, uint8_t color);
|
||||
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();
|
||||
uint32_t do_pixel_word_read();
|
||||
void do_rex3_command();
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
|
Loading…
Reference in New Issue
Block a user