diff options
Diffstat (limited to 'src/devices/bus/interpro/sr/gt.cpp')
-rw-r--r-- | src/devices/bus/interpro/sr/gt.cpp | 193 |
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..a4fa7d18304 --- /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 >_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 >_screen = m_screen[0]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_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 >_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 >_screen = m_screen[0]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_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 >_screen = m_screen[1]; + + gt_screen.ramdac->screen_update(screen, bitmap, cliprect, >_screen.vram[gt_screen.primary ? 0x000000 : GT_BUFFER_SIZE]); + + return 0; +} |