-sgi_mc_device: Basic VDMA support, address translation is currently broken. [Ryan Holtz]

-newport: Various changes, nw
This commit is contained in:
mooglyguy 2019-02-10 01:55:53 +01:00 committed by MooglyGuy
parent 8ed8f42a30
commit ea6d72aa5e
4 changed files with 255 additions and 105 deletions

View File

@ -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();
}
}

View File

@ -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;

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 (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);

View File

@ -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;