summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author angelosa <lordkale4@gmail.com>2022-05-25 00:47:11 +0200
committer angelosa <lordkale4@gmail.com>2022-05-25 00:47:11 +0200
commit6e723211f5a5842e6ab44f848ea66031e4aeb40b (patch)
tree4f624470cb6fe960d6d218343fd7fcd6035209e0
parente6180e3510bef6ea8ffb6abddf64d7d3006829ed (diff)
lindbergh.cpp: quick and dirty VGA control, just to have a video outputlindbergh_exp
-rw-r--r--src/devices/video/gf7600gs.cpp124
-rw-r--r--src/devices/video/gf7600gs.h21
-rw-r--r--src/devices/video/pc_vga.cpp5
-rw-r--r--src/devices/video/pc_vga.h2
-rw-r--r--src/mame/drivers/lindbergh.cpp14
5 files changed, 163 insertions, 3 deletions
diff --git a/src/devices/video/gf7600gs.cpp b/src/devices/video/gf7600gs.cpp
index 075c95c5628..fa44143d11e 100644
--- a/src/devices/video/gf7600gs.cpp
+++ b/src/devices/video/gf7600gs.cpp
@@ -19,6 +19,7 @@ void geforce_7600gs_device::map3(address_map &map)
geforce_7600gs_device::geforce_7600gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: pci_device(mconfig, GEFORCE_7600GS, tag, owner, clock)
+ , m_vga(*this, finder_base::DUMMY_TAG)
{
}
@@ -31,7 +32,130 @@ void geforce_7600gs_device::device_start()
add_rom_from_region();
}
+void geforce_7600gs_device::legacy_memory_map(address_map &map)
+{
+ map(0xa0000, 0xbffff).rw(FUNC(geforce_7600gs_device::vram_r), FUNC(geforce_7600gs_device::vram_w));
+}
+
+void geforce_7600gs_device::legacy_io_map(address_map &map)
+{
+ map(0x03b0, 0x03bf).rw(FUNC(geforce_7600gs_device::vga_3b0_r), FUNC(geforce_7600gs_device::vga_3b0_w));
+ map(0x03c0, 0x03cf).rw(FUNC(geforce_7600gs_device::vga_3c0_r), FUNC(geforce_7600gs_device::vga_3c0_w));
+ map(0x03d0, 0x03df).rw(FUNC(geforce_7600gs_device::vga_3d0_r), FUNC(geforce_7600gs_device::vga_3d0_w));
+}
+
+void geforce_7600gs_device::map_extra(
+ uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
+ uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space
+)
+{
+ // command extensions
+ // VGA control - forward legacy VGA addresses to AGP
+ // TODO: doc implies that is unaffected by base and limit?
+// if (BIT(bridge_control, 3))
+ {
+ memory_space->install_device(0, 0xfffff, *this, &geforce_7600gs_device::legacy_memory_map);
+ io_space->install_device(0, 0x0fff, *this, &geforce_7600gs_device::legacy_io_map);
+ }
+
+ // TODO: ISA control
+ // forward to "primary PCI" (host & LPC?) for A8 or A9 blocks for each 1KB blocks in I/O spaces,
+ // (i.e. $100-$3ff, $500-$7ff, $900-$bff etc.)
+ // even if I/O range is inside base and limits
+// if (BIT(bridge_control, 2))
+ // ...
+}
+
void geforce_7600gs_device::device_reset()
{
pci_device::device_reset();
}
+
+uint8_t geforce_7600gs_device::vram_r(offs_t offset)
+{
+ return downcast<vga_device *>(m_vga.target())->mem_r(offset);
+}
+
+void geforce_7600gs_device::vram_w(offs_t offset, uint8_t data)
+{
+ downcast<vga_device *>(m_vga.target())->mem_w(offset, data);
+}
+
+u32 geforce_7600gs_device::vga_3b0_r(offs_t offset, uint32_t mem_mask)
+{
+ uint32_t result = 0;
+ if (ACCESSING_BITS_0_7)
+ result |= downcast<vga_device *>(m_vga.target())->port_03b0_r(offset * 4 + 0) << 0;
+ if (ACCESSING_BITS_8_15)
+ result |= downcast<vga_device *>(m_vga.target())->port_03b0_r(offset * 4 + 1) << 8;
+ if (ACCESSING_BITS_16_23)
+ result |= downcast<vga_device *>(m_vga.target())->port_03b0_r(offset * 4 + 2) << 16;
+ if (ACCESSING_BITS_24_31)
+ result |= downcast<vga_device *>(m_vga.target())->port_03b0_r(offset * 4 + 3) << 24;
+ return result;
+}
+
+void geforce_7600gs_device::vga_3b0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (ACCESSING_BITS_0_7)
+ downcast<vga_device *>(m_vga.target())->port_03b0_w(offset * 4 + 0, data >> 0);
+ if (ACCESSING_BITS_8_15)
+ downcast<vga_device *>(m_vga.target())->port_03b0_w(offset * 4 + 1, data >> 8);
+ if (ACCESSING_BITS_16_23)
+ downcast<vga_device *>(m_vga.target())->port_03b0_w(offset * 4 + 2, data >> 16);
+ if (ACCESSING_BITS_24_31)
+ downcast<vga_device *>(m_vga.target())->port_03b0_w(offset * 4 + 3, data >> 24);
+}
+
+
+u32 geforce_7600gs_device::vga_3c0_r(offs_t offset, uint32_t mem_mask)
+{
+ uint32_t result = 0;
+ if (ACCESSING_BITS_0_7)
+ result |= downcast<vga_device *>(m_vga.target())->port_03c0_r(offset * 4 + 0) << 0;
+ if (ACCESSING_BITS_8_15)
+ result |= downcast<vga_device *>(m_vga.target())->port_03c0_r(offset * 4 + 1) << 8;
+ if (ACCESSING_BITS_16_23)
+ result |= downcast<vga_device *>(m_vga.target())->port_03c0_r(offset * 4 + 2) << 16;
+ if (ACCESSING_BITS_24_31)
+ result |= downcast<vga_device *>(m_vga.target())->port_03c0_r(offset * 4 + 3) << 24;
+ return result;
+}
+
+void geforce_7600gs_device::vga_3c0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (ACCESSING_BITS_0_7)
+ downcast<vga_device *>(m_vga.target())->port_03c0_w(offset * 4 + 0, data >> 0);
+ if (ACCESSING_BITS_8_15)
+ downcast<vga_device *>(m_vga.target())->port_03c0_w(offset * 4 + 1, data >> 8);
+ if (ACCESSING_BITS_16_23)
+ downcast<vga_device *>(m_vga.target())->port_03c0_w(offset * 4 + 2, data >> 16);
+ if (ACCESSING_BITS_24_31)
+ downcast<vga_device *>(m_vga.target())->port_03c0_w(offset * 4 + 3, data >> 24);
+}
+
+u32 geforce_7600gs_device::vga_3d0_r(offs_t offset, uint32_t mem_mask)
+{
+ uint32_t result = 0;
+ if (ACCESSING_BITS_0_7)
+ result |= downcast<vga_device *>(m_vga.target())->port_03d0_r(offset * 4 + 0) << 0;
+ if (ACCESSING_BITS_8_15)
+ result |= downcast<vga_device *>(m_vga.target())->port_03d0_r(offset * 4 + 1) << 8;
+ if (ACCESSING_BITS_16_23)
+ result |= downcast<vga_device *>(m_vga.target())->port_03d0_r(offset * 4 + 2) << 16;
+ if (ACCESSING_BITS_24_31)
+ result |= downcast<vga_device *>(m_vga.target())->port_03d0_r(offset * 4 + 3) << 24;
+ return result;
+}
+
+void geforce_7600gs_device::vga_3d0_w(offs_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (ACCESSING_BITS_0_7)
+ downcast<vga_device *>(m_vga.target())->port_03d0_w(offset * 4 + 0, data >> 0);
+ if (ACCESSING_BITS_8_15)
+ downcast<vga_device *>(m_vga.target())->port_03d0_w(offset * 4 + 1, data >> 8);
+ if (ACCESSING_BITS_16_23)
+ downcast<vga_device *>(m_vga.target())->port_03d0_w(offset * 4 + 2, data >> 16);
+ if (ACCESSING_BITS_24_31)
+ downcast<vga_device *>(m_vga.target())->port_03d0_w(offset * 4 + 3, data >> 24);
+}
diff --git a/src/devices/video/gf7600gs.h b/src/devices/video/gf7600gs.h
index db13718c6da..22d1c39e5bd 100644
--- a/src/devices/video/gf7600gs.h
+++ b/src/devices/video/gf7600gs.h
@@ -6,21 +6,40 @@
#pragma once
#include "machine/pci.h"
+#include "video/pc_vga.h"
class geforce_7600gs_device : public pci_device {
public:
- geforce_7600gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subdevice_id)
+ template <typename T> geforce_7600gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t subdevice_id, T &&vga_tag)
: geforce_7600gs_device(mconfig, tag, owner, clock)
{
set_ids_agp(0x10de02e1, 0xa1, subdevice_id);
+ m_vga.set_tag(std::forward<T>(vga_tag));
}
geforce_7600gs_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ void legacy_memory_map(address_map &map);
+ void legacy_io_map(address_map &map);
+
protected:
virtual void device_start() override;
virtual void device_reset() override;
+ virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
+ uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
+
private:
+ required_device<vga_device> m_vga;
+
+ u8 vram_r(offs_t offset);
+ void vram_w(offs_t offset, uint8_t data);
+ u32 vga_3b0_r(offs_t offset, uint32_t mem_mask = ~0);
+ void vga_3b0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+ u32 vga_3c0_r(offs_t offset, uint32_t mem_mask = ~0);
+ void vga_3c0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+ u32 vga_3d0_r(offs_t offset, uint32_t mem_mask = ~0);
+ void vga_3d0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
+
void map1(address_map &map);
void map2(address_map &map);
void map3(address_map &map);
diff --git a/src/devices/video/pc_vga.cpp b/src/devices/video/pc_vga.cpp
index a553813a8d7..ed0173d8f86 100644
--- a/src/devices/video/pc_vga.cpp
+++ b/src/devices/video/pc_vga.cpp
@@ -1322,7 +1322,8 @@ uint8_t vga_device::crtc_reg_read(uint8_t index)
res = vga.crtc.line_compare & 0xff;
break;
default:
- printf("Unhandled CRTC reg r %02x\n",index);
+ logerror("Unhandled CRTC reg r %02x\n", index);
+ res = m_test_fallback[index];
break;
}
return res;
@@ -1361,6 +1362,7 @@ void vga_device::recompute_params()
recompute_params_clock(1, ((vga.miscellaneous_output & 0xc) ? XTAL(28'636'363) : XTAL(25'174'800)).value());
}
+
void vga_device::crtc_reg_write(uint8_t index, uint8_t data)
{
/* Doom does this */
@@ -1508,6 +1510,7 @@ void vga_device::crtc_reg_write(uint8_t index, uint8_t data)
break;
default:
logerror("Unhandled CRTC reg w %02x %02x\n",index,data);
+ m_test_fallback[index] = data;
break;
}
}
diff --git a/src/devices/video/pc_vga.h b/src/devices/video/pc_vga.h
index 2c32c25cbb0..2856a251b4c 100644
--- a/src/devices/video/pc_vga.h
+++ b/src/devices/video/pc_vga.h
@@ -111,6 +111,8 @@ protected:
return res;
}
+ u8 m_test_fallback[256]{};
+
struct vga_t
{
diff --git a/src/mame/drivers/lindbergh.cpp b/src/mame/drivers/lindbergh.cpp
index 490e2ec8e64..e98f9552c77 100644
--- a/src/mame/drivers/lindbergh.cpp
+++ b/src/mame/drivers/lindbergh.cpp
@@ -368,6 +368,7 @@ Sega 2005
#include "sound/pci-ac97.h"
#include "sound/sb0400.h"
#include "video/gf7600gs.h"
+#include "video/pc_vga.h"
class lindbergh_state : public driver_device
{
@@ -379,9 +380,12 @@ public:
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
+
+ required_device<vga_device> m_vga;
};
lindbergh_state::lindbergh_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag)
+ , m_vga(*this, "vga")
{
}
@@ -397,10 +401,18 @@ void lindbergh_state::lindbergh(machine_config &config)
{
PENTIUM4(config, "maincpu", 28000000U*5); /* Actually Celeron D at 2,8 GHz */
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
+ screen.set_raw(XTAL(25'174'800), 900, 0, 640, 526, 0, 480);
+ screen.set_screen_update(m_vga, FUNC(vga_device::screen_update));
+
+ VGA(config, m_vga, 0);
+ m_vga->set_screen("screen");
+ m_vga->set_vram_size(64*1024*1024);
+
PCI_ROOT (config, "pci", 0);
I82875P_HOST (config, "pci:00.0", 0, 0x103382c0, "maincpu", 512*1024*1024);
I82875P_AGP (config, "pci:01.0", 0);
- GEFORCE_7600GS (config, "pci:01.0:00.0", 0, 0x10de02e1);
+ GEFORCE_7600GS (config, "pci:01.0:00.0", 0, 0x10de02e1, m_vga);
I82875P_OVERFLOW (config, "pci:06.0", 0, 0x103382c0);
PCI_BRIDGE (config, "pci:1c.0", 0, 0x808625ae, 0x02);
I82541 (config, "pci:1c.0:00.0", 0, 0x103382c0);