summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/catseye.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/catseye.cpp')
-rw-r--r--src/devices/video/catseye.cpp1224
1 files changed, 1224 insertions, 0 deletions
diff --git a/src/devices/video/catseye.cpp b/src/devices/video/catseye.cpp
new file mode 100644
index 00000000000..c79e3b246f5
--- /dev/null
+++ b/src/devices/video/catseye.cpp
@@ -0,0 +1,1224 @@
+// license:BSD-3-Clause
+// copyright-holders:Sven Schnelle
+
+#include "emu.h"
+#include "catseye.h"
+
+#define LOG_VRAM (LOG_GENERAL << 1)
+#define LOG_REG (LOG_GENERAL << 2)
+#define LOG_WMOVE (LOG_GENERAL << 3)
+
+//#define VERBOSE (LOG_WMOVE|LOG_REG|LOG_GENERAL)
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(CATSEYE, catseye_device, "catseye", "HP Catseye ASIC")
+
+catseye_device::catseye_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ m_vram(*this, { "^vram_video", "^vram_overlay"}),
+ m_int_write_func(*this),
+ m_blink_timer(nullptr)
+{
+}
+
+catseye_device::catseye_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ catseye_device(mconfig, CATSEYE, tag, owner, clock)
+{
+}
+
+
+void catseye_device::device_start()
+{
+ m_int_write_func.resolve_safe();
+
+ m_blink_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(catseye_device::blink_callback), this));
+ m_blink_timer->adjust(attotime::from_hz(3));
+
+ save_item(NAME(m_changed));
+ save_item(NAME(m_blink_state));
+ save_item(NAME(m_write_enable), 2);
+ save_item(NAME(m_read_enable), 2);
+ save_item(NAME(m_fb_enable), 2);
+ save_item(NAME(m_display_enable));
+ save_item(NAME(m_blink_enable));
+ save_item(NAME(m_sync_enable));
+ save_item(NAME(m_in_vblank));
+ save_item(NAME(m_wm_int_pending));
+ save_item(NAME(m_wm_int_enable));
+ save_item(NAME(m_vblank_int_enable));
+ save_item(NAME(m_vblank_int_pending));
+ save_item(NAME(m_rugsc));
+ save_item(NAME(m_misc));
+ save_item(NAME(m_wmx));
+ save_item(NAME(m_wmwidth));
+ save_item(NAME(m_wmheight));
+ save_item(NAME(m_wmsourcex));
+ save_item(NAME(m_wmsourcey));
+ save_item(NAME(m_wmdestx));
+ save_item(NAME(m_wmdesty));
+ save_item(NAME(m_wmclipleft));
+ save_item(NAME(m_wmclipright));
+ save_item(NAME(m_wmcliptop));
+ save_item(NAME(m_wmclipbottom));
+ save_item(NAME(m_patterns));
+ save_item(NAME(m_linepath));
+ save_item(NAME(m_linetype));
+ save_item(NAME(m_prr), 2);
+ save_item(NAME(m_wrr), 2);
+ save_item(NAME(m_trr), 2);
+ save_item(NAME(m_trrctl), 2);
+ save_item(NAME(m_color), 2);
+ save_item(NAME(m_vb), 2);
+ save_item(NAME(m_acntrl));
+ save_item(NAME(m_planemode), 2);
+ save_item(NAME(m_status));
+}
+
+void catseye_device::device_reset()
+{
+ LOG("%s\n", __func__);
+
+ for(int i = 0; i < 2; i++) {
+ m_read_enable[i] = 0;
+ m_write_enable[i] = 0;
+ m_fb_enable[i] = 0;
+
+ m_prr[i] = 0;
+ m_wrr[i] = 0;
+ m_trr[i] = 0;
+ m_trrctl[i] = 0;
+ m_color[i] = 0;
+ m_vb[i] = 0;
+ m_planemode[i] = 0;
+ std::fill(m_patterns[i].begin(), m_patterns[i].end(), 0);
+ }
+ m_acntrl = 0;
+ m_blink_enable = 0;
+ m_display_enable = m_plane_mask_h;
+ m_rugsc = 0;
+ m_wmwidth = 0;
+ m_wmheight = 0;
+ m_wmsourcex = 0;
+ m_wmsourcey = 0;
+ m_wmdestx = 0;
+ m_wmdesty = 0;
+ m_wmclipleft = 0;
+ m_wmclipright = 0;
+ m_wmcliptop = 0;
+ m_wmclipbottom = 0;
+
+ m_linepath = 0;
+ m_linetype = 0;
+}
+
+void catseye_device::update_int()
+{
+ LOG("%s: pending %d, enabled %d\n", __func__, m_wm_int_pending, m_wm_int_enable);
+ if ((m_wm_int_enable && m_wm_int_pending ) ||
+ (m_vblank_int_enable && m_vblank_int_pending))
+ m_int_write_func(m_plane);
+ else
+ m_int_write_func(0);
+}
+
+TIMER_CALLBACK_MEMBER(catseye_device::blink_callback)
+{
+ m_blink_timer->adjust(attotime::from_hz(5));
+ m_blink_state ^= true;
+ m_changed = true;
+}
+
+void catseye_device::execute_rule(const bool src, const int rule, bool &dst) const
+{
+ switch (rule & 0x0f) {
+ case CATSEYE_REPLACE_RULE_CLEAR:
+ dst = false;
+ break;
+
+ case CATSEYE_REPLACE_RULE_SRC_AND_DST:
+ dst &= src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_SRC_AND_NOT_DST:
+ dst = !dst & src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_SRC:
+ dst = src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOT_SRC_AND_DST:
+ dst &= !src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOP:
+ break;
+
+ case CATSEYE_REPLACE_RULE_SRC_XOR_DST:
+ dst ^= src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_SRC_OR_DST:
+ dst |= src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOT_SRC_AND_NOT_DST:
+ dst = !dst & !src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOT_SRC_XOR_DST:
+ dst ^= !src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOT_DST:
+ dst ^= true;
+ break;
+
+ case CATSEYE_REPLACE_RULE_SRC_OR_NOT_DST:
+ dst = src | !dst;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOT_SRC:
+ dst = !src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOT_SRC_OR_DST:
+ dst |= !src;
+ break;
+
+ case CATSEYE_REPLACE_RULE_NOT_SRC_OR_NOT_DST:
+ dst = !src | !dst;
+ break;
+
+ case CATSEYE_REPLACE_RULE_SET:
+ dst = true;
+ break;
+
+ }
+}
+
+template<int idx>
+void catseye_device::window_move()
+{
+
+ if (!m_fb_enable[idx])
+ return;
+
+ LOGMASKED(LOG_WMOVE, "%s%d: %3ux%3u -> %3ux%3u / %3ux%3u planemode %04x wrr %04x, trr %04x m_trrctl %04x acntr %04x\n",
+ __func__, idx, m_wmsourcex, m_wmsourcey, m_wmdestx, m_wmdesty, m_wmwidth, m_wmheight, m_planemode[idx],
+ m_wrr[idx], m_trr[idx], m_trrctl[idx], m_acntrl);
+
+ int line, endline, lineincr;
+
+ if (m_wmdesty > m_wmsourcey) {
+ /* move down */
+ line = m_wmheight-1;
+ endline = -1;
+ lineincr = -1;
+ } else {
+ /* move up */
+ line = 0;
+ endline = m_wmheight;
+ lineincr = 1;
+ }
+
+ int startcolumn, endcolumn, columnincr;
+ if (m_wmdestx > m_wmsourcex) {
+ /* move right */
+ startcolumn = m_wmwidth-1;
+ endcolumn = -1;
+ columnincr = -1;
+ } else {
+ /* move left */
+ startcolumn = 0;
+ endcolumn = m_wmwidth;
+ columnincr = 1;
+ }
+
+ for ( ; line != endline; line += lineincr) {
+ for (int column = startcolumn; column != endcolumn; column += columnincr) {
+ const int sx = m_wmsourcex + column;
+ const int sy = m_wmsourcey + line;
+ const int dx = m_wmdestx + column;
+ const int dy = m_wmdesty + line;
+
+ if ((m_misc & CATSEYE_MISC_ENABLE_CLIP) &&
+ (dy < m_wmcliptop ||
+ (dy > m_wmclipbottom) ||
+ (dx < m_wmclipleft) ||
+ (dx > m_wmclipright))) {
+ continue;
+ }
+
+ bool dst = false;
+
+ if (m_trrctl[idx] & 0x0100) {
+ bool bit = m_patterns[idx][(m_plane << 4) | (dy & 0xf)] & (1 << (dx & 0xf));
+ switch (m_trr[idx] >> 8) {
+
+ case 0xf0:
+ dst = bit;
+ break;
+
+ default:
+ logerror("%s: unknown trr %02x\n", __func__, m_trr[idx] >> 8);
+ break;
+ }
+ } else {
+ bool const src = get_vram_pixel_plane<idx>(sx, sy);
+ dst = get_vram_pixel<idx>(dx, dy);
+ execute_rule(src, m_wrr[idx] & 0x0f, dst);
+ }
+ modify_vram<idx>(dx, dy, dst);
+ }
+ }
+}
+
+
+template<int idx>
+void catseye_device::draw_pixel(int x, int y, int color)
+{
+ if ((m_misc & CATSEYE_MISC_ENABLE_CLIP) &&
+ (x < m_wmclipleft ||
+ x > m_wmclipright ||
+ y < m_wmcliptop ||
+ y > m_wmclipbottom))
+ return;
+
+ bool src = color & m_plane_mask_l;
+ bool dst = get_vram_pixel<idx>(x, y);
+ execute_rule(src, (m_prr[idx] >> 8) & 0x0f, dst);
+ modify_vram<idx>(x, y, dst);
+ m_status |= CATSEYE_STATUS_UNCLIPPED;
+}
+
+template<int idx>
+void catseye_device::draw_line()
+{
+ const int color = m_color[idx] >> 8;
+ int x1 = m_wmsourcex;
+ int y1 = m_wmsourcey;
+ int x2 = m_wmdestx;
+ int y2 = m_wmdesty;
+ int dx, dy, t, e, x, y, incy, diago, horiz;
+ bool c1;
+
+ LOGMASKED(LOG_WMOVE, "%s%d %dx%d -> %dx%d, color %d\n",
+ __func__, idx, m_wmsourcex, m_wmsourcey, m_wmdestx, m_wmdesty, color);
+
+ c1 = false;
+ incy = 1;
+
+ if (x2 > x1)
+ dx = x2 - x1;
+ else
+ dx = x1 - x2;
+
+ if (y2 > y1)
+ dy = y2 - y1;
+ else
+ dy = y1 - y2;
+
+ if (dy > dx) {
+ t = y2;
+ y2 = x2;
+ x2 = t;
+
+ t = y1;
+ y1 = x1;
+ x1 = t;
+
+ t = dx;
+ dx = dy;
+ dy = t;
+
+ c1 = true;
+ }
+
+ if (x1 > x2) {
+ t = y2;
+ y2 = y1;
+ y1 = t;
+
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+
+ horiz = dy << 1;
+ diago = (dy - dx) << 1;
+ e = (dy << 1) - dx;
+
+ if (y1 <= y2)
+ incy = 1;
+ else
+ incy = -1;
+
+ x = x1;
+ y = y1;
+
+ if (c1) {
+ do {
+ draw_pixel<idx>(y, x, color);
+
+ if (e > 0) {
+ y += incy;
+ e += diago;
+ } else {
+ e += horiz;
+ }
+ x++;
+ } while (x <= x2);
+ } else {
+ do {
+ draw_pixel<idx>(x, y, color);
+ if (e > 0) {
+ y += incy;
+ e += diago;
+ } else {
+ e += horiz;
+ }
+ x++;
+ } while (x <= x2);
+ }
+
+}
+
+template<int idx>
+void catseye_device::trigger_wm()
+{
+ if (!m_fb_enable[idx])
+ return;
+
+ if ((m_vb[idx] & CATSEYE_VB_VECTOR) && (m_rugsc == 0x10))
+ draw_line<idx>();
+ else if (m_rugsc == 0x90)
+ window_move<idx>();
+ else
+ logerror("%s: unsupported rugcmd: %04x vb %04x\n", __func__, m_rugsc, m_vb[idx]);
+}
+
+template<int idx>
+u16 catseye_device::vram_r_bit(offs_t offset)
+{
+ u16 ret = 0;
+
+ offset &= ~0x7;
+
+ for(int i = 0; i < 16; i++)
+ ret |= get_vram_offset_plane<idx>(offset * 2 + 15 - i) ? (1 << i) : 0;
+ return ret;
+}
+
+template<int idx>
+u16 catseye_device::vram_r_word(offs_t offset, u16 mem_mask)
+{
+ u16 ret = 0;
+
+ if (mem_mask & m_plane_mask_l)
+ ret |= get_vram_offset<idx>(offset * 2 + 1);
+
+ if (mem_mask & m_plane_mask_h)
+ ret |= get_vram_offset<idx>(offset * 2) << 8;
+
+ return ret;
+}
+
+template<int idx>
+u16 catseye_device::vram_r(offs_t offset, u16 mem_mask)
+{
+ if (m_acntrl & 0x100)
+ return vram_r_bit<idx>(offset);
+ else
+ return vram_r_word<idx>(offset, mem_mask);
+}
+
+READ16_MEMBER(catseye_device::vram_r)
+{
+ uint16_t ret = 0;
+
+ if (m_acntrl & 0x200)
+ ret = vram_r<VRAM_OVERLAY_PLANE>(offset, mem_mask);
+ else
+ ret = vram_r<VRAM_VIDEO_PLANE>(offset, mem_mask);
+
+ LOGMASKED(LOG_VRAM, "%s: %04x: %04x(%04x)\n", __func__, offset << 1, ret, mem_mask);
+ return ret;
+}
+
+template<int idx>
+void catseye_device::vram_w_bit(offs_t offset, u16 data, u16 mem_mask)
+{
+ offset &= ~0x7;
+
+ for (int i = 0; i < 16; i++) {
+
+ const int bit = (1 << i);
+
+ if (!(mem_mask & bit))
+ continue;
+
+ bool dst = get_vram_offset<idx>(offset * 2 + 15 - i);
+ execute_rule(data & bit, (m_prr[idx] >> 8) & 0x0f, dst);
+ modify_vram_offset<idx>(offset * 2 + 15 - i, dst);
+ }
+}
+
+template<int idx>
+void catseye_device::vram_w_word(offs_t offset, u16 data, u16 mem_mask)
+{
+ if (mem_mask & m_plane_mask_l) {
+ const bool src = data & m_plane_mask_l;
+ bool dst = get_vram_offset<idx>(offset * 2 + 1);
+ execute_rule(src, (m_prr[idx] >> 8) & 0x0f, dst);
+ modify_vram_offset<idx>(offset * 2 + 1, dst);
+ }
+
+ if (mem_mask & m_plane_mask_h) {
+ const bool src = data & m_plane_mask_h;
+ bool dst = get_vram_offset<idx>(offset * 2);
+ execute_rule(src, (m_prr[idx] >> 8) & 0x0f, dst);
+ modify_vram_offset<idx>(offset * 2, dst);
+ }
+}
+
+template<int idx>
+void catseye_device::vram_w(offs_t offset, u16 data, u16 mem_mask)
+{
+ if (m_acntrl & 0x100)
+ vram_w_bit<idx>(offset, data, mem_mask);
+ else
+ vram_w_word<idx>(offset, data, mem_mask);
+}
+
+WRITE16_MEMBER(catseye_device::vram_w)
+{
+ LOGMASKED(LOG_VRAM, "%s: %04x: %04x(%04x)\n", __func__, offset << 1, data, mem_mask);
+
+ if (m_fb_enable[0])
+ vram_w<VRAM_VIDEO_PLANE>(offset, data, mem_mask);
+
+ if (m_fb_enable[1])
+ vram_w<VRAM_OVERLAY_PLANE>(offset, data, mem_mask);
+}
+
+WRITE16_MEMBER(catseye_device::ctrl_w)
+{
+ bool trigger = false;
+
+ if (m_write_enable[0] && offset >= 0x200 && offset < 0x280) {
+ COMBINE_DATA(&m_patterns[0][offset - 0x200]);
+ LOGMASKED(LOG_REG, "W PATTERNS1[%03d] = %04x\n", offset - 0x200, m_patterns[0][offset - 0x200]);
+ return;
+ }
+
+ if (m_write_enable[1] && offset >= 0x300 && offset < 0x380) {
+ COMBINE_DATA(&m_patterns[1][offset - 0x300]);
+ LOGMASKED(LOG_REG, "W PATTERNS2[%03d] = %04x\n", offset - 0x300, m_patterns[1][offset - 0x300]);
+ return;
+ }
+
+ switch(offset) {
+ case TOPCAT_REG_ENABLE_BLINK_PLANES:
+ if (mem_mask & 0xff00)
+ m_blink_enable = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "enable blink plane: %04x\n", m_blink_enable);
+ break;
+
+ case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
+ if (mem_mask & 0xff00)
+ m_display_enable = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "display enable %04x\n", m_display_enable);
+ break;
+
+ case TOPCAT_REG_SYNC_ENABLE:
+ if (mem_mask & 0xff00)
+ m_sync_enable = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "sync enable: %04x\n", m_sync_enable);
+ break;
+
+ case TOPCAT_REG_WMOVE_INTRQ:
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMOVE_INTRQ = %04x\n", data);
+ m_wm_int_pending = 0;
+ update_int();
+ break;
+
+ case TOPCAT_REG_WMOVE_IE:
+ if (mem_mask & 0xff00)
+ m_wm_int_enable = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMOVE_IE = %04x\n", m_wm_int_enable);
+ update_int();
+ break;
+
+ case TOPCAT_REG_VBLANK_IE:
+ if (mem_mask & 0xff00)
+ m_vblank_int_enable = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMOVE_IE = %04x\n", m_vblank_int_enable);
+ update_int();
+ break;
+
+ case CATSEYE_REG_WMX:
+ COMBINE_DATA(&m_wmx);
+ COMBINE_DATA(&m_wmsourcex);
+ COMBINE_DATA(&m_wmdestx);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMX = %04x\n", m_wmx);
+ break;
+
+ case CATSEYE_REG_RUG_SC:
+ COMBINE_DATA(&m_rugsc);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_RUG_SC = %04x\n", m_rugsc);
+ break;
+
+ case TOPCAT_REG_WMWIDTH:
+ case CATSEYE_REG_WMWIDTH:
+ COMBINE_DATA(&m_wmwidth);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMWIDTH = %04x\n", m_wmwidth);
+ break;
+
+ case TOPCAT_REG_WMHEIGHT:
+ case CATSEYE_REG_WMHEIGHT:
+ COMBINE_DATA(&m_wmheight);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMHEIGHT = %04x\n", m_wmheight);
+ break;
+
+ case CATSEYE_REG_LINEPATH:
+ COMBINE_DATA(&m_linepath);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_LINEPATH = %04x\n", m_linepath);
+ break;
+
+ case CATSEYE_REG_LINETYPE:
+ COMBINE_DATA(&m_linetype);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_LINETYPE = %04x\n", m_linetype);
+ break;
+
+
+ case TOPCAT_REG_WMSOURCEX:
+ case CATSEYE_REG_WMSOURCEX:
+ COMBINE_DATA(&m_wmsourcex);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMSOURCEX = %04x\n", m_wmsourcex);
+ break;
+
+ case TOPCAT_REG_WMSOURCEY:
+ case CATSEYE_REG_WMSOURCEY:
+ COMBINE_DATA(&m_wmsourcey);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMSOURCEY = %04x\n", m_wmsourcey);
+ break;
+
+ case TOPCAT_REG_WMDESTX:
+ case CATSEYE_REG_WMDESTX:
+ COMBINE_DATA(&m_wmdestx);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMDESTX = %04x\n", m_wmdestx);
+ break;
+
+ case TOPCAT_REG_WMDESTY:
+ case CATSEYE_REG_WMDESTY:
+ COMBINE_DATA(&m_wmdesty);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMDESTY = %04x\n", m_wmdesty);
+ break;
+
+ case CATSEYE_REG_WMCLIPLEFT:
+ COMBINE_DATA(&m_wmclipleft);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMCLIPLEFT = %04x\n", m_wmclipleft);
+ break;
+
+ case CATSEYE_REG_WMCLIPRIGHT:
+ COMBINE_DATA(&m_wmclipright);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMCLIPRIGHT = %04x\n", m_wmclipright);
+ break;
+
+ case CATSEYE_REG_WMCLIPTOP:
+ COMBINE_DATA(&m_wmcliptop);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMCLIPTOP = %04x\n", m_wmcliptop);
+ break;
+
+ case CATSEYE_REG_WMCLIPBOTTOM:
+ COMBINE_DATA(&m_wmclipbottom);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WMCLIPBOTTOM = %04x\n", m_wmclipbottom);
+ break;
+
+ case CATSEYE_REG_TWMWIDTH:
+ COMBINE_DATA(&m_wmwidth);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TWMWIDTH = %04x\n", m_wmwidth);
+ trigger = true;
+ break;
+
+ case CATSEYE_REG_TWMHEIGHT:
+ COMBINE_DATA(&m_wmheight);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TWMHEIGHT = %04x\n", m_wmheight);
+ trigger = true;
+ break;
+
+ case CATSEYE_REG_TWMSOURCEX:
+ COMBINE_DATA(&m_wmsourcex);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TWMSOURCEX = %04x\n", m_wmsourcex);
+ trigger = true;
+ break;
+
+ case CATSEYE_REG_TWMSOURCEY:
+ COMBINE_DATA(&m_wmsourcey);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TWMSOURCEY = %04x\n", m_wmsourcey);
+ trigger = true;
+ break;
+
+ case CATSEYE_REG_TWMDESTX:
+ COMBINE_DATA(&m_wmdestx);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TWMDESTX = %04x\n", m_wmdestx);
+ trigger = true;
+ break;
+
+ case CATSEYE_REG_TWMDESTY:
+ COMBINE_DATA(&m_wmdesty);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TWMDESTY = %04x\n", m_wmdesty);
+ trigger = true;
+ break;
+
+ case TOPCAT_REG_START_WMOVE:
+ if (m_write_enable[0]) {
+ LOGMASKED(LOG_REG, "W TOPCAT_REG_START_WMOVE = %04x\n", data);
+ window_move<0>();
+ if (m_wm_int_enable) {
+ m_wm_int_pending = m_plane_mask_h;
+ update_int();
+ }
+ }
+ break;
+
+ case CATSEYE_REG_STATUS:
+ COMBINE_DATA(&m_status);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_STATUS = %04x\n", m_status);
+ break;
+
+ case CATSEYE_REG_STATUS+1:
+ case CATSEYE_REG_STATUS+2:
+ // unknown
+ break;
+
+
+ // TC 1 registers
+ case TOPCAT_REG_READ_ENABLE_PLANE:
+ case CATSEYE_REG_TCREN1:
+ if (mem_mask & m_plane_mask_h)
+ m_read_enable[0] = data & m_plane_mask_l;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_READ_ENABLE1 = %04x\n", m_read_enable[0]);
+ break;
+
+ case TOPCAT_REG_WRITE_ENABLE_PLANE:
+ case CATSEYE_REG_TCWEN1:
+ if (mem_mask & m_plane_mask_h)
+ m_write_enable[0] = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WRITE_ENABLE1 = %04x\n", m_write_enable[0]);
+ break;
+
+ case TOPCAT_REG_FB_WRITE_ENABLE:
+ case CATSEYE_REG_FBEN1:
+ if (mem_mask & m_plane_mask_h)
+ m_fb_enable[0] = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_FBEN1 = %04x\n", m_fb_enable[0]);
+ break;
+
+ case TOPCAT_REG_PRR:
+ case CATSEYE_REG_PRR1:
+ if (!m_write_enable[0])
+ break;
+ COMBINE_DATA(&m_prr[0]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_PRR1 = %04x\n", m_prr[0]);
+ break;
+
+ case TOPCAT_REG_WRR:
+ case CATSEYE_REG_WRR1:
+ if (!m_write_enable[0])
+ break;
+ COMBINE_DATA(&m_wrr[0]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WRR1 = %04x\n", m_wrr[0]);
+ break;
+
+ case CATSEYE_REG_TRR1:
+ if (!m_write_enable[0])
+ break;
+ COMBINE_DATA(&m_trr[0]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TRR1 = %04x\n", m_trr[0]);
+ break;
+
+ case CATSEYE_REG_VB1:
+ if (!m_write_enable[0])
+ break;
+ COMBINE_DATA(&m_vb[0]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_VB1 = %04x\n", m_vb[0]);
+ break;
+
+ case CATSEYE_REG_COLOR1:
+ COMBINE_DATA(&m_color[0]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_COLOR1 = %04x\n", m_color[0]);
+ break;
+
+ case CATSEYE_REG_TRRCTL1:
+ if (!m_write_enable[0])
+ break;
+ COMBINE_DATA(&m_trrctl[0]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TRRCTL1 = %04x\n", m_trrctl[0]);
+ break;
+
+ case CATSEYE_REG_ACNTL1:
+ if (!m_write_enable[0])
+ break;
+ COMBINE_DATA(&m_acntrl);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_ACNTL1 = %04x\n", m_acntrl);
+ break;
+
+ case CATSEYE_REG_PLANEMODE1:
+ COMBINE_DATA(&m_planemode[0]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_PLANEMODE1 = %04x\n", m_planemode[0]);
+ break;
+
+ // TC 2 registers
+ case CATSEYE_REG_TCREN2:
+ if (mem_mask & 0xff00)
+ m_read_enable[1] = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_READ_ENABLE2 = %04x\n", m_read_enable[1]);
+ break;
+
+ case CATSEYE_REG_TCWEN2:
+ if (mem_mask & 0xff00)
+ m_write_enable[1] = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_READ_ENABLE2 = %04x\n", m_write_enable[1]);
+ break;
+
+ case CATSEYE_REG_FBEN2:
+ if (mem_mask & 0xff00)
+ m_fb_enable[1] = data & m_plane_mask_h;
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_READ_ENABLE2 = %04x\n", m_fb_enable[1]);
+ break;
+
+ case CATSEYE_REG_PRR2:
+ if (!m_write_enable[1])
+ break;
+ COMBINE_DATA(&m_prr[1]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_PRR2 = %04x\n", m_prr[1]);
+ break;
+
+ case CATSEYE_REG_WRR2:
+ if (!m_write_enable[1])
+ break;
+ COMBINE_DATA(&m_wrr[1]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_WRR2 = %04x\n", m_wrr[1]);
+ break;
+
+ case CATSEYE_REG_TRR2:
+ if (!m_write_enable[1])
+ break;
+ COMBINE_DATA(&m_trr[1]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TRR2 = %04x\n", m_trr[1]);
+ break;
+
+ case CATSEYE_REG_VB2:
+ if (!m_write_enable[1])
+ break;
+
+ COMBINE_DATA(&m_vb[1]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_VB2 = %04x\n", m_vb[1]);
+ break;
+
+ case CATSEYE_REG_COLOR2:
+ COMBINE_DATA(&m_color[1]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_COLOR2 = %04x\n", m_color[1]);
+ break;
+
+ case CATSEYE_REG_TRRCTL2:
+ if (!m_write_enable[1])
+ break;
+
+ COMBINE_DATA(&m_trrctl[1]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_TRRCTL2 = %04x\n", m_trrctl[1]);
+ break;
+
+ case CATSEYE_REG_ACNTL2:
+ if (!m_write_enable[1])
+ break;
+
+ COMBINE_DATA(&m_acntrl);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_ACNTL2 = %04x\n", m_acntrl);
+ break;
+
+ case CATSEYE_REG_PLANEMODE2:
+ if (!m_write_enable[1])
+ break;
+
+ COMBINE_DATA(&m_planemode[1]);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_PLANEMODE2 = %04x\n", m_planemode[1]);
+ break;
+ case CATSEYE_REG_RUG_REV:
+ COMBINE_DATA(&m_misc);
+ LOGMASKED(LOG_REG, "W CATSEYE_REG_MISC = %04x\n", m_misc);
+ break;
+ default:
+ logerror("%s: unknown: %04x = %04x (mask %04x)\n", __func__, offset << 1, data, mem_mask);
+ return;
+ }
+
+ if (m_fb_enable[0] && trigger)
+ trigger_wm<VRAM_VIDEO_PLANE>();
+
+ if (m_fb_enable[1] && trigger)
+ trigger_wm<VRAM_OVERLAY_PLANE>();
+
+}
+
+READ16_MEMBER(catseye_device::ctrl_r)
+{
+ uint16_t ret;
+
+ if (offset >= 0x200 && offset < 0x280) {
+ LOGMASKED(LOG_REG, "R PATTERNS1[%03d] = %04x\n", offset - 0x200, m_patterns[0][offset - 0x200]);
+ return m_patterns[0][offset - 0x200];
+ }
+
+ if (offset >= 0x300 && offset < 0x380) {
+ LOGMASKED(LOG_REG, "R PATTERNS2[%03d] = %04x\n", offset - 0x300, m_patterns[1][offset - 0x300]);
+ return m_patterns[1][offset - 0x300];
+ }
+
+ switch(offset) {
+ case TOPCAT_REG_ENABLE_BLINK_PLANES:
+ ret = m_blink_enable;
+ break;
+
+ case TOPCAT_REG_SYNC_ENABLE:
+ ret = m_sync_enable;
+ break;
+
+ case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
+ ret = m_display_enable;
+ break;
+
+ case TOPCAT_REG_VBLANK:
+ ret = m_in_vblank;
+ LOGMASKED(LOG_REG, "R VBLANK = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMOVE_INTRQ:
+ ret = m_wm_int_pending;
+ LOGMASKED(LOG_REG, "R WMOVE_INTRQ = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_VBLANK_INTRQ:
+ ret = m_vblank_int_pending;
+ LOGMASKED(LOG_REG, "R VBLANK_INTRQ = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMOVE_IE:
+ ret = m_wm_int_enable;
+ LOGMASKED(LOG_REG, "R WMOVE_IE = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_VBLANK_IE:
+ ret = m_vblank_int_enable;
+ LOGMASKED(LOG_REG, "R VBLANK_IE = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_RUG_SC:
+ ret = m_rugsc;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_RUG_SC = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMWIDTH:
+ case CATSEYE_REG_WMWIDTH:
+ ret = m_wmwidth;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMWIDTH = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMHEIGHT:
+ case CATSEYE_REG_WMHEIGHT:
+ ret = m_wmheight;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMHEIGHT = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_LINEPATH:
+ ret = m_linepath;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_LINEPATH = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_LINETYPE:
+ ret = m_linetype;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_LINETYPE = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMSOURCEX:
+ case CATSEYE_REG_WMSOURCEX:
+ ret = m_wmsourcex;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMSOURCEX = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMSOURCEY:
+ case CATSEYE_REG_WMSOURCEY:
+ ret = m_wmsourcey;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMSOURCEY = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMDESTX:
+ case CATSEYE_REG_WMDESTX:
+ ret = m_wmdestx;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMDESTX = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WMDESTY:
+ case CATSEYE_REG_WMDESTY:
+ ret = m_wmdesty;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMDESTY = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_WMCLIPLEFT:
+ ret = m_wmclipleft;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMCLIPLEFT = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_WMCLIPRIGHT:
+ ret = m_wmclipright;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMCLIPRIGHT = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_WMCLIPTOP:
+ ret = m_wmcliptop;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMCLIPTOP = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_WMCLIPBOTTOM:
+ ret = m_wmclipbottom;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WMCLIPBOTTOM = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TWMWIDTH:
+ ret = m_wmwidth;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TWMWIDTH = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TWMHEIGHT:
+ ret = m_wmheight;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TWMHEIGHT = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TWMSOURCEX:
+ ret = m_wmsourcex;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TWMSOURCEX = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TWMSOURCEY:
+ ret = m_wmsourcey;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TWMSOURCEY = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TWMDESTX:
+ ret = m_wmdestx;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TWMDESTX = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TWMDESTY:
+ ret = m_wmdesty;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TWMDESTY = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_STATUS:
+ ret = CATSEYE_STATUS_READY | CATSEYE_STATUS_NO_DAUGHTERBOARD;
+ ret |= m_status & ~CATSEYE_STATUS_VBLANK;
+ if (m_in_vblank)
+ ret |= CATSEYE_STATUS_VBLANK;
+
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_STATUS = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_STATUS+1:
+ case CATSEYE_REG_STATUS+2:
+ // unknown
+ ret = 0;
+ break;
+
+ case TOPCAT_REG_START_WMOVE:
+ m_wm_int_pending = 0;
+ update_int();
+ ret = 0;
+ break;
+
+ case CATSEYE_REG_RUG_REV:
+ ret = m_misc;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_RUG_REV = %04x\n", ret);
+ break;
+
+ // TC1
+ case TOPCAT_REG_FB_WRITE_ENABLE:
+ case CATSEYE_REG_FBEN1:
+ ret = m_fb_enable[0];
+ break;
+
+ case TOPCAT_REG_READ_ENABLE_PLANE:
+ case CATSEYE_REG_TCREN1:
+ ret = m_read_enable[0];
+ break;
+
+ case TOPCAT_REG_WRITE_ENABLE_PLANE:
+ case CATSEYE_REG_TCWEN1:
+ ret = m_write_enable[0];
+ break;
+
+ case TOPCAT_REG_PRR:
+ case CATSEYE_REG_PRR1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_prr[0];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_PRR1 = %04x\n", ret);
+ break;
+
+ case TOPCAT_REG_WRR:
+ case CATSEYE_REG_WRR1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_wrr[0];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WRR1 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TRR1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_trr[0];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TRR1 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_COLOR1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_color[0];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_COLOR1 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_VB1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_vb[0];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_VB1 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TRRCTL1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_trrctl[0];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TRRCTL1 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_ACNTL1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_acntrl;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_ACNTL1 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_PLANEMODE1:
+ if (m_read_enable[0])
+ return 0;
+
+ ret = m_planemode[0];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_PLANEMODE1 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_BARC_REV1:
+ ret = 0x0100;
+ break;
+
+ // TC2
+ case CATSEYE_REG_FBEN2:
+ ret = m_fb_enable[1];
+ break;
+
+ case CATSEYE_REG_TCREN2:
+ ret = m_read_enable[1];
+ break;
+
+ case CATSEYE_REG_TCWEN2:
+ ret = m_write_enable[1];
+ break;
+
+ case CATSEYE_REG_PRR2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_prr[1];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_PRR2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_WRR2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_wrr[1];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_WRR2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TRR2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_trr[1];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TRR2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_COLOR2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_color[1];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_COLOR2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_VB2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_vb[1];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_VB2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_TRRCTL2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_trrctl[1];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_TRRCTL2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_ACNTL2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_acntrl;
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_ACNTL2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_PLANEMODE2:
+ if (m_read_enable[1])
+ return 0;
+
+ ret = m_planemode[1];
+ LOGMASKED(LOG_REG, "R CATSEYE_REG_PLANEMODE2 = %04x\n", ret);
+ break;
+
+ case CATSEYE_REG_BARC_REV2:
+ ret = 0x0100;
+ break;
+
+ default:
+ logerror("%s: unknown: %04x (mask %04x)\n", __func__, offset << 1, mem_mask);
+ return space.unmap();
+ }
+ return ret;
+}
+
+WRITE_LINE_MEMBER(catseye_device::vblank_w)
+{
+ m_in_vblank = state ? m_plane_mask_h : 0;
+ if (state && m_vblank_int_enable)
+ m_vblank_int_pending = m_plane_mask_h;
+}