summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/pci/neon250.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/pci/neon250.cpp')
-rw-r--r--src/devices/bus/pci/neon250.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/devices/bus/pci/neon250.cpp b/src/devices/bus/pci/neon250.cpp
new file mode 100644
index 00000000000..b0908182e9c
--- /dev/null
+++ b/src/devices/bus/pci/neon250.cpp
@@ -0,0 +1,188 @@
+// license:BSD-3-Clause
+// copyright-holders:
+/**************************************************************************************************
+
+VideoLogic PowerVR Neon 250
+
+TODO:
+- stub device;
+- detects 0Kb of RAM in SDD test, plays with pvr_io_map $54 (IIC Interface B);
+
+**************************************************************************************************/
+
+#include "emu.h"
+#include "neon250.h"
+
+#define LOG_WARN (1U << 1)
+#define LOG_TODO (1U << 2) // log unimplemented registers
+
+#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_TODO)
+//#define LOG_OUTPUT_FUNC osd_printf_info
+#include "logmacro.h"
+
+#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
+#define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__)
+
+
+DEFINE_DEVICE_TYPE(NEON250, neon250_device, "neon250", "VideoLogic PowerVR Neon 250 (PMX1)")
+
+neon250_device::neon250_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : pci_card_device(mconfig, type, tag, owner, clock)
+ , m_svga(*this, "svga")
+ , m_vga_rom(*this, "vga_rom")
+{
+ // PowerVR Neon 250 AGP (NEC branded)
+ set_ids_agp(0x10330067, 0x02, 0x10100120);
+}
+
+neon250_device::neon250_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : neon250_device(mconfig, NEON250, tag, owner, clock)
+{
+}
+
+ROM_START( neon250 )
+ ROM_REGION32_LE( 0x20000, "vga_rom", ROMREGION_ERASEFF )
+ ROM_SYSTEM_BIOS( 0, "neon250", "NEC Neon 250" )
+ ROMX_LOAD( "n0020331.bin", 0x000000, 0x20000, CRC(e76008f5) SHA1(1ddda1494d5b32148e2c9e7a6557f00ee9cffea6), ROM_BIOS(0) )
+// ROMX_LOAD( "ppvr201i.bin", 0x000000, 0x10000, CRC(b6e763c9) SHA1(1e1fecbb663dde5295a9db98dde70a4e1bd8338d), ROM_BIOS(0) )
+// ROMX_LOAD( "b1002816.bin", 0x000000, 0x10000, CRC(d3cf607a) SHA1(8fea7c3e678bc585ed5729d7f1a4b203bae8d15d), ROM_BIOS(0) )
+ // from VGA Legacy MkIII, bad
+// ROMX_LOAD( "neon250agp.vbi", 0x000000, 0x009200, CRC(41a46c28) SHA1(f99482b906436d9b1db25e68de5a2bc96a192128) BAD_DUMP, ROM_BIOS(0) )
+ROM_END
+
+const tiny_rom_entry *neon250_device::device_rom_region() const
+{
+ return ROM_NAME(neon250);
+}
+
+void neon250_device::device_add_mconfig(machine_config &config)
+{
+ 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_svga, FUNC(vga_device::screen_update));
+
+ // TODO: PVR "VGA Emulator"
+ VGA(config, m_svga, 0);
+ m_svga->set_screen("screen");
+ m_svga->set_vram_size(32*1024*1024);
+}
+
+
+
+void neon250_device::device_start()
+{
+ pci_card_device::device_start();
+
+ add_map( 64*1024*1024, M_MEM | M_PREF, FUNC(neon250_device::pvr_fb_map));
+ add_map( 16*1024, M_MEM | M_PREF, FUNC(neon250_device::pvr_mmio_map));
+ add_map( 128*1024, M_MEM | M_PREF, FUNC(neon250_device::vga_fb_map));
+ add_map( 2*1024, M_MEM, FUNC(neon250_device::vga_mmio_map));
+ // not indicated, assume no-pref again
+ add_map( 256, M_IO, FUNC(neon250_device::pvr_io_map));
+
+ add_rom((u8 *)m_vga_rom->base(), 128*1024 );
+ expansion_rom_base = 0xc0000;
+
+ // INTA#
+ intr_pin = 1;
+}
+
+void neon250_device::device_reset()
+{
+ pci_card_device::device_reset();
+
+ command = 0x0000;
+ // can VGA palette snoop, can MWI (bit 4)
+ command_mask = 0x0037;
+ // medium DEVSELB + fast back to back + new cap support
+ // can set AGP bit 5
+ status = 0x0290;
+
+ remap_cb();
+}
+
+u8 neon250_device::capptr_r()
+{
+ return 0x60;
+}
+
+void neon250_device::config_map(address_map &map)
+{
+ pci_device::config_map(map);
+
+ // AGP
+ map(0x40, 0x43).lr32(NAME([] { return 0x0010'0002; }));
+ // AGP 1x & 2x + SBA + 31 RQ
+ map(0x44, 0x47).lr32(NAME([] { return 0x1f00'0203; }));
+
+// map(0x4c, 0x4d) Discard Timer
+// map(0x50, 0x50) 16T Timer
+// map(0x54, 0x54) 8T Timer
+// map(0x58, 0x59) SSVIDW
+// map(0x5a, 0x5b) Subsystem Control
+// map(0x5c, 0x5d) SSDEVW
+
+ // Power management
+ // PCI PM 1.0 compliant + Device Specific Init (DSI) + D1 & D2 support
+ // TODO: disables capptr if AGP is unset
+ map(0x60, 0x63).lr32(NAME([] { return 0x0621'4001; }));
+
+// map(0x70, 0x71) AGP PLL Control
+// map(0x72, 0x73) Core PLL Control
+}
+
+
+
+void neon250_device::pvr_fb_map(address_map &map)
+{
+
+}
+
+void neon250_device::pvr_mmio_map(address_map &map)
+{
+}
+
+void neon250_device::pvr_io_map(address_map &map)
+{
+}
+
+void neon250_device::vga_fb_map(address_map &map)
+{
+}
+
+void neon250_device::vga_mmio_map(address_map &map)
+{
+}
+
+// TODO: this should really be a subclass of VGA
+void neon250_device::legacy_memory_map(address_map &map)
+{
+ map(0xa0000, 0xbffff).rw(FUNC(neon250_device::vram_r), FUNC(neon250_device::vram_w));
+}
+
+void neon250_device::legacy_io_map(address_map &map)
+{
+ map(0, 0x02f).m(m_svga, FUNC(vga_device::io_map));
+}
+
+uint8_t neon250_device::vram_r(offs_t offset)
+{
+ return downcast<vga_device *>(m_svga.target())->mem_r(offset);
+}
+
+void neon250_device::vram_w(offs_t offset, uint8_t data)
+{
+ downcast<vga_device *>(m_svga.target())->mem_w(offset, data);
+}
+
+void neon250_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)
+{
+ if (command & 7)
+ {
+ memory_space->install_readwrite_handler(0xa0000, 0xbffff, read8sm_delegate(*this, FUNC(neon250_device::vram_r)), write8sm_delegate(*this, FUNC(neon250_device::vram_w)));
+
+ io_space->install_device(0x03b0, 0x03df, *this, &neon250_device::legacy_io_map);
+ //memory_space->install_rom(0xc0000, 0xcffff, (void *)expansion_rom);
+ }
+}