summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatarGravatar mooglyguy <therealmogminer@gmail.com>2020-03-01 13:19:49 +0100
committerGravatarGravatar mooglyguy <therealmogminer@gmail.com>2020-03-01 13:20:42 +0100
commit7b5219935aa4cedd293013110ef6030e224c4b61 (patch)
tree7e3f66df1686f2ea33d017b74a01348f81bf3179
parentd808dd967a60336c67681189f5205cc18c869474 (diff)
downloadmame-7b5219935aa4cedd293013110ef6030e224c4b61.tar.xz
mame-7b5219935aa4cedd293013110ef6030e224c4b61.zip
-s3virge: Plumbed out linear framebuffer support. Fixes graphics in 'Analog 801' demoscene demo. [Ryan Holtz]
-rw-r--r--src/devices/bus/isa/isa.cpp5
-rw-r--r--src/devices/bus/isa/isa.h1
-rw-r--r--src/devices/bus/isa/s3virge.cpp94
-rw-r--r--src/devices/bus/isa/s3virge.h10
-rw-r--r--src/devices/bus/isa/svga_s3.cpp56
-rw-r--r--src/devices/bus/isa/svga_s3.h9
6 files changed, 166 insertions, 9 deletions
diff --git a/src/devices/bus/isa/isa.cpp b/src/devices/bus/isa/isa.cpp
index df21453268f..9537febc93c 100644
--- a/src/devices/bus/isa/isa.cpp
+++ b/src/devices/bus/isa/isa.cpp
@@ -371,6 +371,11 @@ bool isa8_device::is_option_rom_space_available(offs_t start, int size)
return true;
}
+void isa8_device::unmap_readwrite(offs_t start, offs_t end)
+{
+ m_memspace->unmap_readwrite(start, end);
+}
+
// interrupt request from isa card
WRITE_LINE_MEMBER( isa8_device::irq2_w ) { m_out_irq2_cb(state); }
WRITE_LINE_MEMBER( isa8_device::irq3_w ) { m_out_irq3_cb(state); }
diff --git a/src/devices/bus/isa/isa.h b/src/devices/bus/isa/isa.h
index 4eefa1ff548..4cd032a1a9e 100644
--- a/src/devices/bus/isa/isa.h
+++ b/src/devices/bus/isa/isa.h
@@ -155,6 +155,7 @@ public:
void unmap_device(offs_t start, offs_t end) const { m_iospace->unmap_readwrite(start, end); }
void unmap_bank(offs_t start, offs_t end);
void unmap_rom(offs_t start, offs_t end);
+ void unmap_readwrite(offs_t start, offs_t end);
bool is_option_rom_space_available(offs_t start, int size);
// FIXME: shouldn't need to expose this
diff --git a/src/devices/bus/isa/s3virge.cpp b/src/devices/bus/isa/s3virge.cpp
index 111d87002e8..9fa8739a13d 100644
--- a/src/devices/bus/isa/s3virge.cpp
+++ b/src/devices/bus/isa/s3virge.cpp
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Barry Rodewald
/*
- * s3virge.c
+ * s3virge.cpp
*
* Implementation of the S3 Virge series of video card
*
@@ -42,6 +42,7 @@ s3virge_vga_device::s3virge_vga_device(const machine_config &mconfig, const char
s3virge_vga_device::s3virge_vga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: s3_vga_device(mconfig, type, tag, owner, clock)
+ , m_linear_config_changed_cb(*this)
{
}
@@ -64,9 +65,7 @@ void s3virge_vga_device::device_start()
{
zero();
- int x;
- int i;
- for (i = 0; i < 0x100; i++)
+ for (int i = 0; i < 0x100; i++)
set_pen_color(i, 0, 0, 0);
// Avoid an infinite loop when displaying. 0 is not possible anyway.
@@ -90,6 +89,7 @@ void s3virge_vga_device::device_start()
memset(&s3, 0, sizeof(s3));
memset(&s3virge, 0, sizeof(s3virge));
s3virge.linear_address = 0x70000000;
+ s3virge.linear_address_size_full = 0x10000;
s3virge.s3d.cmd_fifo_slots_free = 16;
save_item(s3virge.s3d.pattern,"S3D Pattern Data");
save_item(s3virge.s3d.reg[0],"S3D Registers: BitBLT");
@@ -98,8 +98,10 @@ void s3virge_vga_device::device_start()
save_item(s3virge.s3d.reg[3],"S3D Registers: 3D Line");
save_item(s3virge.s3d.reg[4],"S3D Registers: 3D Triangle");
+ m_linear_config_changed_cb.resolve_safe();
+
// Initialise hardware graphics cursor colours, Windows 95 doesn't touch the registers for some reason
- for(x=0;x<4;x++)
+ for (int x = 0; x < 4; x++)
{
s3.cursor_fg[x] = 0xff;
s3.cursor_bg[x] = 0x00;
@@ -581,8 +583,14 @@ bit 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the
break;
case 0x58:
+ {
+ const uint8_t old_size = s3virge.linear_address_size;
+ const bool old_enable = s3virge.linear_address_enable;
+ const bool size_changed = old_size != s3virge.linear_address_size;
+
s3virge.linear_address_size = data & 0x03;
s3virge.linear_address_enable = data & 0x10;
+
switch(data & 0x03)
{
case LAW_64K:
@@ -598,16 +606,39 @@ bit 0-1 DAC Register Select Bits. Passed to the RS2 and RS3 pins on the
s3virge.linear_address_size_full = 0x400000;
break;
}
+
+ if ((s3virge.linear_address_enable != old_enable) || size_changed)
+ {
+ m_linear_config_changed_cb(s3virge.linear_address_enable);
+ }
+
LOGREG("CR58: write %02x\n", data);
break;
+ }
case 0x59:
+ {
+ const uint32_t old_address = s3virge.linear_address;
s3virge.linear_address = (s3virge.linear_address & 0x00ff0000) | (data << 24);
LOGREG("Linear framebuffer address = %08x\n",s3virge.linear_address);
+
+ if (old_address != s3virge.linear_address && s3virge.linear_address_enable)
+ {
+ m_linear_config_changed_cb(1);
+ }
break;
+ }
case 0x5a:
+ {
+ const uint32_t old_address = s3virge.linear_address;
s3virge.linear_address = (s3virge.linear_address & 0xff000000) | (data << 16);
LOGREG("Linear framebuffer address = %08x\n",s3virge.linear_address);
+
+ if (old_address != s3virge.linear_address && s3virge.linear_address_enable)
+ {
+ m_linear_config_changed_cb(1);
+ }
break;
+ }
/*
3d4h index 5Dh (R/W): Extended Horizontal Overflow Register (80x +)
@@ -887,12 +918,12 @@ void s3virge_vga_device::add_command(int cmd_type)
// add command to S3D FIFO
if(s3virge.s3d.cmd_fifo_slots_free == 0)
{
- LOGMMIO("Attempt to add command when all command slots are full\n");
+ LOGCMD("Attempt to add command when all command slots are full\n");
return;
}
memcpy(s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_next_ptr].reg,s3virge.s3d.reg[cmd_type],256*4);
s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_next_ptr].op_type = cmd_type;
- LOGMMIO("Added command type %i cmd %08x ptr %u\n",s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_next_ptr].op_type,s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_next_ptr].reg[S3D_REG_COMMAND],s3virge.s3d.cmd_fifo_next_ptr);
+ LOGCMD("Added command type %i cmd %08x ptr %u\n",s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_next_ptr].op_type,s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_next_ptr].reg[S3D_REG_COMMAND],s3virge.s3d.cmd_fifo_next_ptr);
s3virge.s3d.cmd_fifo_next_ptr++;
if(s3virge.s3d.cmd_fifo_next_ptr >= 16)
s3virge.s3d.cmd_fifo_next_ptr = 0;
@@ -909,6 +940,18 @@ void s3virge_vga_device::command_start()
switch(cmd_type)
{
+ case OP_2DLINE:
+ LOGCMD("2D Line command (unsupported) [%u]\n", s3virge.s3d.cmd_fifo_current_ptr);
+ break;
+ case OP_2DPOLY:
+ LOGCMD("2D Poly command (unsupported) [%u]\n", s3virge.s3d.cmd_fifo_current_ptr);
+ break;
+ case OP_3DLINE:
+ LOGCMD("3D Line command (unsupported) [%u]\n", s3virge.s3d.cmd_fifo_current_ptr);
+ break;
+ case OP_3DTRI:
+ LOGCMD("3D Tri command (unsupported) [%u]\n", s3virge.s3d.cmd_fifo_current_ptr);
+ break;
case OP_BITBLT:
s3virge.s3d.state = S3D_STATE_BITBLT;
s3virge.s3d.busy = true;
@@ -936,7 +979,7 @@ void s3virge_vga_device::command_start()
s3virge.s3d.bitblt_current_pixel = 0;
s3virge.s3d.bitblt_pixel_pos = 0;
s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_PAT_BG_CLR] = 0xffffffff; // win31 never sets this?
- LOGMMIO("Started BitBLT command [%u]\n", s3virge.s3d.cmd_fifo_current_ptr);
+ LOGCMD("Started BitBLT command [%u]\n", s3virge.s3d.cmd_fifo_current_ptr);
//if(((s3virge.s3d.cmd_fifo[s3virge.s3d.cmd_fifo_current_ptr].reg[S3D_REG_COMMAND] & 0x01fe0000) >> 17) == 0xf0) machine().debug_break();
break;
}
@@ -958,10 +1001,31 @@ void s3virge_vga_device::command_finish()
command_start();
else
s3virge.s3d.busy = false;
- //machine().debug_break();
+
LOGMMIO("Command finished [%u] (%u slots free)\n",s3virge.s3d.cmd_fifo_current_ptr,s3virge.s3d.cmd_fifo_slots_free);
}
+void s3virge_vga_device::line2d_step()
+{
+ command_finish();
+}
+
+void s3virge_vga_device::poly2d_step()
+{
+ command_finish();
+}
+
+void s3virge_vga_device::line3d_step()
+{
+ command_finish();
+}
+
+void s3virge_vga_device::poly3d_step()
+{
+ command_finish();
+}
+
+
uint32_t s3virge_vga_device::GetROP(uint8_t rop, uint32_t src, uint32_t dst, uint32_t pat)
{
uint32_t ret = 0;
@@ -1373,6 +1437,18 @@ void s3virge_vga_device::device_timer(emu_timer &timer, device_timer_id id, int
case S3D_STATE_IDLE:
m_draw_timer->adjust(attotime::zero);
break;
+ case S3D_STATE_2DLINE:
+ line2d_step();
+ break;
+ case S3D_STATE_2DPOLY:
+ poly2d_step();
+ break;
+ case S3D_STATE_3DLINE:
+ line3d_step();
+ break;
+ case S3D_STATE_3DPOLY:
+ poly3d_step();
+ break;
case S3D_STATE_BITBLT:
bitblt_step();
break;
diff --git a/src/devices/bus/isa/s3virge.h b/src/devices/bus/isa/s3virge.h
index 997377fcd38..558dcbad189 100644
--- a/src/devices/bus/isa/s3virge.h
+++ b/src/devices/bus/isa/s3virge.h
@@ -22,6 +22,8 @@ public:
// construction/destruction
s3virge_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ auto linear_config_changed() { return m_linear_config_changed_cb.bind(); }
+
virtual READ8_MEMBER(port_03b0_r) override;
virtual WRITE8_MEMBER(port_03b0_w) override;
virtual READ8_MEMBER(port_03c0_r) override;
@@ -54,6 +56,7 @@ public:
uint32_t get_linear_address() { return s3virge.linear_address; }
void set_linear_address(uint32_t addr) { s3virge.linear_address = addr; }
uint8_t get_linear_address_size() { return s3virge.linear_address_size; }
+ uint32_t get_linear_address_size_full() { return s3virge.linear_address_size_full; }
bool is_linear_address_active() { return s3virge.linear_address_enable; }
bool is_new_mmio_active() { return s3.cr53 & 0x08; }
uint16_t dest_stride()
@@ -236,11 +239,18 @@ protected:
}
uint32_t GetROP(uint8_t rop, uint32_t src, uint32_t dst, uint32_t pat);
bool advance_pixel();
+
+ devcb_write_line m_linear_config_changed_cb;
+
private:
emu_timer* m_draw_timer;
void bitblt_step();
void bitblt_colour_step();
void bitblt_monosrc_step();
+ void line2d_step();
+ void poly2d_step();
+ void line3d_step();
+ void poly3d_step();
void add_command(int cmd_type);
void command_start();
void command_finish();
diff --git a/src/devices/bus/isa/svga_s3.cpp b/src/devices/bus/isa/svga_s3.cpp
index ddac8fc77c1..26225d06215 100644
--- a/src/devices/bus/isa/svga_s3.cpp
+++ b/src/devices/bus/isa/svga_s3.cpp
@@ -150,6 +150,17 @@ void isa16_s3virge_device::device_add_mconfig(machine_config &config)
screen.set_screen_update(m_vga, FUNC(s3virge_vga_device::screen_update));
S3VIRGE(config, m_vga, 0).set_screen("screen");
+ m_vga->linear_config_changed().set(FUNC(isa16_s3virge_device::linear_config_changed_w));
+}
+
+//-------------------------------------------------
+// linear_config_changed_w - callback to indicate
+// enabling, disabling, or changig of the linear
+// framebuffer configuration.
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER(isa16_s3virge_device::linear_config_changed_w)
+{
}
//-------------------------------------------------
@@ -229,6 +240,33 @@ void isa16_s3virgedx_device::device_add_mconfig(machine_config &config)
screen.set_screen_update(m_vga, FUNC(s3virgedx_vga_device::screen_update));
S3VIRGEDX(config, m_vga, 0).set_screen("screen");
+ m_vga->linear_config_changed().set(FUNC(isa16_s3virgedx_device::linear_config_changed_w));
+}
+
+//-------------------------------------------------
+// linear_config_changed_w - callback to indicate
+// enabling, disabling, or changig of the linear
+// framebuffer configuration.
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER(isa16_s3virgedx_device::linear_config_changed_w)
+{
+ const bool old = m_lfb_enable;
+ m_lfb_enable = state;
+ if (state)
+ {
+ if (old)
+ {
+ m_isa->unmap_readwrite(m_lfb_start, m_lfb_end);
+ }
+ m_lfb_start = m_vga->get_linear_address();
+ m_lfb_end = m_lfb_start + m_vga->get_linear_address_size_full() - 1;
+ m_isa->install_memory(m_lfb_start, m_lfb_end, read8_delegate(*m_vga, FUNC(s3virge_vga_device::fb_r)), write8_delegate(*m_vga, FUNC(s3virge_vga_device::fb_w)));
+ }
+ else
+ {
+ m_isa->unmap_readwrite(m_lfb_start, m_lfb_end);
+ }
}
//-------------------------------------------------
@@ -271,6 +309,10 @@ void isa16_s3virgedx_device::device_start()
m_isa->install_device(0x03d0, 0x03df, read8_delegate(*m_vga, FUNC(s3virge_vga_device::port_03d0_r)), write8_delegate(*m_vga, FUNC(s3virge_vga_device::port_03d0_w)));
m_isa->install_memory(0xa0000, 0xbffff, read8_delegate(*m_vga, FUNC(s3virge_vga_device::mem_r)), write8_delegate(*m_vga, FUNC(s3virge_vga_device::mem_w)));
+
+ save_item(NAME(m_lfb_enable));
+ save_item(NAME(m_lfb_start));
+ save_item(NAME(m_lfb_end));
}
//-------------------------------------------------
@@ -279,6 +321,9 @@ void isa16_s3virgedx_device::device_start()
void isa16_s3virgedx_device::device_reset()
{
+ m_lfb_enable = m_vga->is_linear_address_active();
+ m_lfb_start = m_vga->get_linear_address();
+ m_lfb_end = m_lfb_start + m_vga->get_linear_address_size_full() - 1;
}
@@ -309,6 +354,17 @@ void isa16_stealth3d2kpro_device::device_add_mconfig(machine_config &config)
screen.set_screen_update(m_vga, FUNC(s3virgedx_rev1_vga_device::screen_update));
S3VIRGEDX1(config, m_vga, 0).set_screen("screen");
+ m_vga->linear_config_changed().set(FUNC(isa16_stealth3d2kpro_device::linear_config_changed_w));
+}
+
+//-------------------------------------------------
+// linear_config_changed_w - callback to indicate
+// enabling, disabling, or changig of the linear
+// framebuffer configuration.
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER(isa16_stealth3d2kpro_device::linear_config_changed_w)
+{
}
//-------------------------------------------------
diff --git a/src/devices/bus/isa/svga_s3.h b/src/devices/bus/isa/svga_s3.h
index 3889a2ed8e8..3c4e891c750 100644
--- a/src/devices/bus/isa/svga_s3.h
+++ b/src/devices/bus/isa/svga_s3.h
@@ -58,6 +58,8 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
+ DECLARE_WRITE_LINE_MEMBER(linear_config_changed_w);
+
private:
required_device<s3virge_vga_device> m_vga;
};
@@ -81,8 +83,13 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
+ DECLARE_WRITE_LINE_MEMBER(linear_config_changed_w);
+
private:
required_device<s3virgedx_vga_device> m_vga;
+ bool m_lfb_enable;
+ uint32_t m_lfb_start;
+ uint32_t m_lfb_end;
};
class isa16_stealth3d2kpro_device :
@@ -104,6 +111,8 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
+ DECLARE_WRITE_LINE_MEMBER(linear_config_changed_w);
+
private:
required_device<s3virgedx_vga_device> m_vga;
};