// 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 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(sx, sy); dst = get_vram_pixel(dx, dy); execute_rule(src, m_wrr[Idx] & 0x0f, dst); } modify_vram(dx, dy, dst); } } } template 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(x, y); execute_rule(src, (m_prr[Idx] >> 8) & 0x0f, dst); modify_vram(x, y, dst); m_status |= CATSEYE_STATUS_UNCLIPPED; } template 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(y, x, color); if (e > 0) { y += incy; e += diago; } else { e += horiz; } x++; } while (x <= x2); } else { do { draw_pixel(x, y, color); if (e > 0) { y += incy; e += diago; } else { e += horiz; } x++; } while (x <= x2); } } template void catseye_device::trigger_wm() { if (!m_fb_enable[Idx]) return; if ((m_vb[Idx] & CATSEYE_VB_VECTOR) && (m_rugsc == 0x10)) draw_line(); else if (m_rugsc == 0x90) window_move(); else logerror("%s: unsupported rugcmd: %04x vb %04x\n", __func__, m_rugsc, m_vb[Idx]); } template 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(offset * 2 + 15 - i) ? (1 << i) : 0; return ret; } template 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(offset * 2 + 1); if (mem_mask & m_plane_mask_h) ret |= get_vram_offset(offset * 2) << 8; return ret; } template u16 catseye_device::vram_r(offs_t offset, u16 mem_mask) { if (m_acntrl & 0x100) return vram_r_bit(offset); else return vram_r_word(offset, mem_mask); } READ16_MEMBER(catseye_device::vram_r) { uint16_t ret = 0; if (m_acntrl & 0x200) ret = vram_r(offset, mem_mask); else ret = vram_r(offset, mem_mask); LOGMASKED(LOG_VRAM, "%s: %04x: %04x(%04x)\n", __func__, offset << 1, ret, mem_mask); return ret; } template 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(offset * 2 + 15 - i); execute_rule(data & bit, (m_prr[Idx] >> 8) & 0x0f, dst); modify_vram_offset(offset * 2 + 15 - i, dst); } } template 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(offset * 2 + 1); execute_rule(src, (m_prr[Idx] >> 8) & 0x0f, dst); modify_vram_offset(offset * 2 + 1, dst); } if (mem_mask & m_plane_mask_h) { const bool src = data & m_plane_mask_h; bool dst = get_vram_offset(offset * 2); execute_rule(src, (m_prr[Idx] >> 8) & 0x0f, dst); modify_vram_offset(offset * 2, dst); } } template void catseye_device::vram_w(offs_t offset, u16 data, u16 mem_mask) { if (m_acntrl & 0x100) vram_w_bit(offset, data, mem_mask); else vram_w_word(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(offset, data, mem_mask); if (m_fb_enable[1]) vram_w(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(); if (m_fb_enable[1] && trigger) trigger_wm(); } 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_WMOVE_ACTIVE: ret = 0; break; 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; }