summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/interpro/sr/gt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/interpro/sr/gt.cpp')
-rw-r--r--src/devices/bus/interpro/sr/gt.cpp193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp
new file mode 100644
index 00000000000..c4ed9109792
--- /dev/null
+++ b/src/devices/bus/interpro/sr/gt.cpp
@@ -0,0 +1,193 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+/*
+ * An emulation of GT graphics for Intergraph InterPro.
+ *
+ * TODO
+ * - control register (including primary/secondary buffer selection)
+ * - DP8510V BITBLT unit
+ * - custom Bresenham line drawing ASIC
+ * - support GT+, GTII, GTII+
+ * - reset behaviour
+ */
+
+#include "emu.h"
+#include "screen.h"
+
+#include "gt.h"
+
+#define VERBOSE 0
+#include "logmacro.h"
+
+DEVICE_ADDRESS_MAP_START(map, 32, mpcb963_device)
+ AM_RANGE(0x00000000, 0x0000007f) AM_READ(idprom_r)
+ AM_RANGE(0x00000080, 0x0000008f) AM_DEVICE8("ramdac0", bt459_device, map, 0xff)
+ AM_RANGE(0x000000b0, 0x000000b3) AM_READWRITE16(control_r, control_w, 0xffff)
+ //AM_RANGE(0x000000d4, 0x000000d7) AM_READWRITE8(, 0xff) // currently unknown
+ //AM_RANGE(0x000000a0, 0x000000a0) AM_READWRITE8(, 0xff) // currently unknown
+ AM_RANGE(0x00400000, 0x005fffff) AM_READWRITE(vram_r, vram_w)
+ADDRESS_MAP_END
+
+DEVICE_ADDRESS_MAP_START(map, 32, mpcba79_device)
+ AM_RANGE(0x00000000, 0x0000007f) AM_READ(idprom_r)
+ AM_RANGE(0x00000080, 0x0000008f) AM_DEVICE8("ramdac0", bt459_device, map, 0xff)
+ AM_RANGE(0x00000090, 0x0000009f) AM_DEVICE8("ramdac1", bt459_device, map, 0xff)
+ AM_RANGE(0x000000b0, 0x000000b3) AM_READWRITE16(control_r, control_w, 0xffff)
+ //AM_RANGE(0x000000d4, 0x000000d7) AM_READWRITE8(, 0xff) // currently unknown
+ //AM_RANGE(0x000000a0, 0x000000a0) AM_READWRITE8(, 0xff) // currently unknown
+ AM_RANGE(0x00400000, 0x007fffff) AM_READWRITE(vram_r, vram_w)
+ADDRESS_MAP_END
+
+ROM_START(mpcb963)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcb963a.bin", 0x0, 0x20, CRC(4cf4562d) SHA1(58bcc2afb66168f1d44a0366b6a5ccc4c22e0f32))
+ROM_END
+
+ROM_START(mpcba79)
+ ROM_REGION(0x80, "idprom", 0)
+ ROM_LOAD32_BYTE("mpcba79a.bin", 0x0, 0x20, CRC(b3b98324) SHA1(77b4ed0bbc6ed19646c4536d9976563f78961408))
+ROM_END
+
+DEFINE_DEVICE_TYPE(MPCB963, mpcb963_device, "mpcb963", "2000 Graphics f/1 1Mp Monitor")
+DEFINE_DEVICE_TYPE(MPCBA79, mpcba79_device, "mpcba79", "2000 Graphics f/2 1Mp Monitors")
+
+/*
+ * The raw screen data here is just a guess for now. Real values will need to
+ * be determined to ensure the cursor positions generated by the Bt459 are
+ * aligned properly on the screen.
+ */
+MACHINE_CONFIG_MEMBER(mpcb963_device::device_add_mconfig)
+ MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS)
+ MCFG_SCREEN_UPDATE_DEVICE("", mpcb963_device, screen_update0)
+ MCFG_DEVICE_ADD("ramdac0", BT459, 0)
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_MEMBER(mpcba79_device::device_add_mconfig)
+ MCFG_SCREEN_ADD("screen0", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS)
+ MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update0)
+ MCFG_DEVICE_ADD("ramdac0", BT459, 0)
+
+ MCFG_SCREEN_ADD("screen1", RASTER)
+ MCFG_SCREEN_RAW_PARAMS(GT_PIXCLOCK, GT_XPIXELS, 0, GT_XPIXELS, GT_YPIXELS, 0, GT_YPIXELS)
+ MCFG_SCREEN_UPDATE_DEVICE("", mpcba79_device, screen_update1)
+ MCFG_DEVICE_ADD("ramdac1", BT459, 0)
+MACHINE_CONFIG_END
+
+gt_device_base::gt_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : sr_card_device_base(mconfig, type, tag, owner, clock)
+{
+}
+
+mpcb963_device::mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : gt_device_base(mconfig, MPCB963, tag, owner, clock)
+ , m_screen{ { { *this, "ramdac0" }, {}, true } }
+{
+}
+
+const tiny_rom_entry *mpcb963_device::device_rom_region() const
+{
+ return ROM_NAME(mpcb963);
+}
+
+void mpcb963_device::device_start()
+{
+ gt_device_base::device_start();
+
+ // allocate double-buffered vram
+ m_screen[0].vram.reset(new u8[GT_VRAM_SIZE]);
+
+ save_item(NAME(m_control));
+ save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM_SIZE);
+}
+
+
+WRITE16_MEMBER(mpcb963_device::control_w)
+{
+ LOG("control_w 0x%04x\n", data);
+
+ m_control = data;
+}
+
+READ32_MEMBER(mpcb963_device::vram_r) const
+{
+ return ((u32 *)m_screen[(offset >> 19) & 1].vram.get())[offset & 0x7ffff];
+}
+
+WRITE32_MEMBER(mpcb963_device::vram_w)
+{
+ const gt_screen_t &gt_screen = m_screen[(offset >> 19) & 1];
+
+ ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask);
+}
+
+u32 mpcb963_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ const gt_screen_t &gt_screen = m_screen[0];
+
+ gt_screen.ramdac->screen_update(screen, bitmap, cliprect, &gt_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]);
+
+ return 0;
+}
+
+mpcba79_device::mpcba79_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : gt_device_base(mconfig, MPCBA79, tag, owner, clock)
+ , m_screen { { { *this, "ramdac0" }, {}, true }, { { *this, "ramdac1" }, {}, true } }
+{
+}
+
+const tiny_rom_entry *mpcba79_device::device_rom_region() const
+{
+ return ROM_NAME(mpcba79);
+}
+
+void mpcba79_device::device_start()
+{
+ gt_device_base::device_start();
+
+ m_screen[0].vram.reset(new u8[GT_VRAM_SIZE]);
+ m_screen[1].vram.reset(new u8[GT_VRAM_SIZE]);
+
+ save_item(NAME(m_control));
+ save_pointer(NAME(m_screen[0].vram.get()), GT_VRAM_SIZE);
+ save_pointer(NAME(m_screen[1].vram.get()), GT_VRAM_SIZE);
+}
+
+WRITE16_MEMBER(mpcba79_device::control_w)
+{
+ LOG("control_w 0x%04x\n", data);
+
+ m_control = data;
+}
+
+READ32_MEMBER(mpcba79_device::vram_r) const
+{
+ return ((u32 *)m_screen[(offset >> 19) & 1].vram.get())[offset & 0x7ffff];
+}
+
+WRITE32_MEMBER(mpcba79_device::vram_w)
+{
+ const gt_screen_t &gt_screen = m_screen[(offset >> 19) & 1];
+
+ ((u32 *)gt_screen.vram.get())[offset & 0x7ffff] = (((u32 *)gt_screen.vram.get())[offset & 0x7ffff] & ~mem_mask) | (data & mem_mask);
+}
+
+u32 mpcba79_device::screen_update0(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ const gt_screen_t &gt_screen = m_screen[0];
+
+ gt_screen.ramdac->screen_update(screen, bitmap, cliprect, &gt_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]);
+
+ return 0;
+}
+
+u32 mpcba79_device::screen_update1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ const gt_screen_t &gt_screen = m_screen[1];
+
+ gt_screen.ramdac->screen_update(screen, bitmap, cliprect, &gt_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]);
+
+ return 0;
+}