From 6e723211f5a5842e6ab44f848ea66031e4aeb40b Mon Sep 17 00:00:00 2001 From: angelosa Date: Wed, 25 May 2022 00:47:11 +0200 Subject: lindbergh.cpp: quick and dirty VGA control, just to have a video output --- src/devices/video/gf7600gs.cpp | 124 +++++++++++++++++++++++++++++++++++++++++ src/devices/video/gf7600gs.h | 21 ++++++- src/devices/video/pc_vga.cpp | 5 +- src/devices/video/pc_vga.h | 2 + src/mame/drivers/lindbergh.cpp | 14 ++++- 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(m_vga.target())->mem_r(offset); +} + +void geforce_7600gs_device::vram_w(offs_t offset, uint8_t data) +{ + downcast(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(m_vga.target())->port_03b0_r(offset * 4 + 0) << 0; + if (ACCESSING_BITS_8_15) + result |= downcast(m_vga.target())->port_03b0_r(offset * 4 + 1) << 8; + if (ACCESSING_BITS_16_23) + result |= downcast(m_vga.target())->port_03b0_r(offset * 4 + 2) << 16; + if (ACCESSING_BITS_24_31) + result |= downcast(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(m_vga.target())->port_03b0_w(offset * 4 + 0, data >> 0); + if (ACCESSING_BITS_8_15) + downcast(m_vga.target())->port_03b0_w(offset * 4 + 1, data >> 8); + if (ACCESSING_BITS_16_23) + downcast(m_vga.target())->port_03b0_w(offset * 4 + 2, data >> 16); + if (ACCESSING_BITS_24_31) + downcast(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(m_vga.target())->port_03c0_r(offset * 4 + 0) << 0; + if (ACCESSING_BITS_8_15) + result |= downcast(m_vga.target())->port_03c0_r(offset * 4 + 1) << 8; + if (ACCESSING_BITS_16_23) + result |= downcast(m_vga.target())->port_03c0_r(offset * 4 + 2) << 16; + if (ACCESSING_BITS_24_31) + result |= downcast(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(m_vga.target())->port_03c0_w(offset * 4 + 0, data >> 0); + if (ACCESSING_BITS_8_15) + downcast(m_vga.target())->port_03c0_w(offset * 4 + 1, data >> 8); + if (ACCESSING_BITS_16_23) + downcast(m_vga.target())->port_03c0_w(offset * 4 + 2, data >> 16); + if (ACCESSING_BITS_24_31) + downcast(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(m_vga.target())->port_03d0_r(offset * 4 + 0) << 0; + if (ACCESSING_BITS_8_15) + result |= downcast(m_vga.target())->port_03d0_r(offset * 4 + 1) << 8; + if (ACCESSING_BITS_16_23) + result |= downcast(m_vga.target())->port_03d0_r(offset * 4 + 2) << 16; + if (ACCESSING_BITS_24_31) + result |= downcast(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(m_vga.target())->port_03d0_w(offset * 4 + 0, data >> 0); + if (ACCESSING_BITS_8_15) + downcast(m_vga.target())->port_03d0_w(offset * 4 + 1, data >> 8); + if (ACCESSING_BITS_16_23) + downcast(m_vga.target())->port_03d0_w(offset * 4 + 2, data >> 16); + if (ACCESSING_BITS_24_31) + downcast(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 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(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 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 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); -- cgit v1.2.3