diff options
Diffstat (limited to 'src/devices/bus/hp_dio/hp98550.cpp')
-rw-r--r-- | src/devices/bus/hp_dio/hp98550.cpp | 234 |
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 |