summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/hp_dio/hp98550.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/hp_dio/hp98550.cpp')
-rw-r--r--src/devices/bus/hp_dio/hp98550.cpp234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/devices/bus/hp_dio/hp98550.cpp b/src/devices/bus/hp_dio/hp98550.cpp
new file mode 100644
index 00000000000..8ec1660d5ce
--- /dev/null
+++ b/src/devices/bus/hp_dio/hp98550.cpp
@@ -0,0 +1,234 @@
+// License:BSD-3-Clause
+// copyright-holders:Sven Schnelle
+/***************************************************************************
+
+HP98550 high-resolution color board
+
+1280x1024 @ 60Hz, 8 bpp
+
+***************************************************************************/
+
+#include "emu.h"
+#include "hp98550.h"
+#include "screen.h"
+#include "video/nereid.h"
+#include "video/catseye.h"
+#include "machine/ram.h"
+
+//#define VERBOSE 1
+#include "logmacro.h"
+
+ROM_START(hp98550)
+ ROM_REGION(0x8000, "hp98550a_rom", 0)
+ ROM_LOAD("98550a.bin", 0x000000, 0x008000, CRC(9d639233) SHA1(d6b23a34850f24525ca5fb36de3deb91196d2dc5))
+ROM_END
+
+DEFINE_DEVICE_TYPE_NS(HPDIO_98550, bus::hp_dio, dio32_98550_device, "dio98550", "HP98550 high-res color DIO video card")
+
+namespace bus { namespace hp_dio {
+
+void dio32_98550_device::device_add_mconfig(machine_config &config)
+{
+ screen_device &screen(SCREEN(config, "hp98550_screen", SCREEN_TYPE_RASTER));
+ screen.set_screen_update(FUNC(dio32_98550_device::screen_update));
+ screen.screen_vblank().set(FUNC(dio32_98550_device::vblank_w));
+ screen.set_raw(XTAL(108'108'000), 1689, 0, m_h_pix, 1066, 0, m_v_pix);
+
+ for (int i = 0; i < CATSEYE_COUNT; i++) {
+ CATSEYE(config, m_catseye[i], XTAL(108'108'000));
+ m_catseye[i]->set_fb_width(m_fb_width);
+ m_catseye[i]->set_fb_height(m_v_pix);
+ m_catseye[i]->set_plane(i);
+ m_catseye[i]->irq_out_cb().set(FUNC(dio32_98550_device::int_w));
+ }
+
+ NEREID(config, m_nereid, 0);
+}
+
+const tiny_rom_entry *dio32_98550_device::device_rom_region() const
+{
+ return ROM_NAME(hp98550);
+}
+
+void dio32_98550_device::map(address_map& map)
+{
+ map(0, 0x3fffff).ram().share("vram_video");
+ map(0x400000, 0x7fffff).ram().share("vram_overlay");
+}
+
+device_memory_interface::space_config_vector dio32_98550_device::memory_space_config() const
+{
+ return space_config_vector {
+ std::make_pair(0, &m_space_config)
+ };
+}
+
+dio32_98550_device::dio32_98550_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ dio32_98550_device(mconfig, HPDIO_98550, tag, owner, clock)
+{
+}
+
+dio32_98550_device::dio32_98550_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ device_dio16_card_interface(mconfig, *this),
+ device_memory_interface(mconfig, *this),
+ m_nereid(*this, "nereid"),
+ m_catseye(*this, "catseye%d", 0),
+ m_space_config("vram", ENDIANNESS_BIG, 8, 23, 0, address_map_constructor(FUNC(dio32_98550_device::map), this)),
+ m_rom(*this, "hp98550a_rom"),
+ m_vram(*this, { "vram_video", "vram_overlay"})
+{
+}
+
+void dio32_98550_device::device_start()
+{
+ save_item(NAME(m_intreg));
+ save_item(NAME(m_ints));
+
+ dio().install_memory(
+ 0x200000, 0x3fffff,
+ read16_delegate(FUNC(dio32_98550_device::vram_r), this),
+ write16_delegate(FUNC(dio32_98550_device::vram_w), this));
+
+ dio().install_memory(
+ 0x560000, 0x56ffff,
+ read16_delegate(FUNC(dio32_98550_device::rom_r), this),
+ write16_delegate(FUNC(dio32_98550_device::rom_w), this));
+
+ dio().install_memory(
+ 0x564000, 0x5648ff,
+ read16_delegate(FUNC(dio32_98550_device::catseye_r), this),
+ write16_delegate(FUNC(dio32_98550_device::catseye_w), this));
+
+ dio().install_memory(
+ 0x566000, 0x5660ff,
+ read16_delegate(FUNC(nereid_device::ctrl_r), &(*m_nereid)),
+ write16_delegate(FUNC(nereid_device::ctrl_w), &(*m_nereid)));
+}
+
+void dio32_98550_device::device_reset()
+{
+ m_intreg = 0;
+ m_ints = 0;
+}
+
+READ16_MEMBER(dio32_98550_device::rom_r)
+{
+ LOG("%s: %04x\n", __func__, offset);
+
+ if (offset == 1)
+ return m_intreg;
+
+ return 0xff00 | m_rom[offset];
+}
+
+WRITE16_MEMBER(dio32_98550_device::rom_w)
+{
+ switch (offset) {
+ case 0:
+ reset();
+ break;
+
+ case 1:
+ m_intreg = data;
+ break;
+
+ default:
+ logerror("%s: %04x = %04x (mask %04x)\n", __func__, offset << 1, data, mem_mask);
+ break;
+ }
+}
+
+READ16_MEMBER(dio32_98550_device::catseye_r)
+{
+ uint16_t ret = 0;
+
+ for (auto &ce: m_catseye)
+ ret |= ce->ctrl_r(space, offset, mem_mask);
+ LOG("%s: %04X = %04X\n", __func__, offset << 1, ret);
+ return ret;
+}
+
+WRITE16_MEMBER(dio32_98550_device::catseye_w)
+{
+ LOG("%s: %04X = %04X\n", __func__, offset << 1, data);
+ for (auto &ce: m_catseye)
+ ce->ctrl_w(space, offset, data, mem_mask);
+}
+
+READ16_MEMBER(dio32_98550_device::vram_r)
+{
+ uint16_t ret = 0;
+
+ for (auto &ce: m_catseye)
+ ret |= ce->vram_r(space, offset, mem_mask);
+
+ return ret;
+}
+
+WRITE16_MEMBER(dio32_98550_device::vram_w)
+{
+ for (auto &ce: m_catseye)
+ ce->vram_w(space, offset, data, mem_mask);
+}
+
+WRITE_LINE_MEMBER(dio32_98550_device::vblank_w)
+{
+ for (auto &ce: m_catseye)
+ ce->vblank_w(state);
+}
+
+WRITE8_MEMBER(dio32_98550_device::int_w)
+{
+ LOG("%s: plane%d = %s\n", __func__, offset, data ? "assert" : "deassert");
+ m_ints &= ~(1 << offset);
+ m_ints |= data;
+ update_int();
+}
+
+void dio32_98550_device::update_int()
+{
+ bool state = m_ints;
+ int line = (m_intreg >> 3) & 7;
+
+ if (!(m_intreg & 0x80))
+ state = false;
+
+ irq1_out(line == 1 && state);
+ irq2_out(line == 2 && state);
+ irq3_out(line == 3 && state);
+ irq4_out(line == 4 && state);
+ irq5_out(line == 5 && state);
+ irq6_out(line == 6 && state);
+ irq7_out(line == 7 && state);
+}
+
+uint32_t dio32_98550_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ bool changed = false;
+ uint8_t mask = 0;
+
+ for (auto &ce: m_catseye)
+ changed |= ce->has_changed();
+
+ if (!changed)
+ return UPDATE_HAS_NOT_CHANGED;
+
+ for (auto &ce: m_catseye)
+ mask |= ce->plane_enabled();
+
+ for (int y = 0; y < m_v_pix; y++) {
+ uint32_t *scanline = &bitmap.pix32(y);
+
+ for (int x = 0; x < m_h_pix; x++) {
+ const int offset = y * m_fb_width +x;
+ uint8_t tmp = m_vram[0][offset] & mask;
+ uint8_t ovl = m_vram[1][offset] & mask;
+ *scanline++ = m_nereid->map_color(tmp, ovl);
+ }
+ }
+ return 0;
+}
+
+} // namespace bus::hp_dio
+} // namespace bus