diff options
author | 2018-08-31 22:06:05 +0200 | |
---|---|---|
committer | 2018-08-31 16:06:05 -0400 | |
commit | 89ae43bfbbbea7353053bacf96c1ca2098c40432 (patch) | |
tree | d70b13ba78c5232c11f90797d59d8b4d83c767cb /src/devices/video/topcat.cpp | |
parent | f0b81ff6aa19a97173d9fee5db8729e86dfa1791 (diff) |
Topcat fixes (#3930)
* topcat: fix display read/write enable register (nw)
* topcat: add (yet) unknown register 0x4a/0x4c to make test software happy (nw)
* topcat: return cursor register contents (nw)
* topcat: add plane_enabled() function (nw)
* topcat: add suport for Pixel Replacement Rules (nw)
* topcat,hp98544,hp98543: add VBLANK register (nw)
* topcat: add interrupt registers (nw)
Diffstat (limited to 'src/devices/video/topcat.cpp')
-rw-r--r-- | src/devices/video/topcat.cpp | 108 |
1 files changed, 93 insertions, 15 deletions
diff --git a/src/devices/video/topcat.cpp b/src/devices/video/topcat.cpp index 959640dd09c..7565dd57791 100644 --- a/src/devices/video/topcat.cpp +++ b/src/devices/video/topcat.cpp @@ -12,6 +12,7 @@ DEFINE_DEVICE_TYPE(TOPCAT, topcat_device, "topcat", "HP Topcat ASIC") topcat_device::topcat_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_cursor_timer(nullptr), + m_int_write_func(*this), m_vram(*this, "^vram") { } @@ -26,13 +27,13 @@ void topcat_device::device_start() m_cursor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(topcat_device::cursor_callback), this)); m_cursor_timer->adjust(attotime::from_hz(3)); + m_int_write_func.resolve_safe(); + save_item(NAME(m_vblank)); save_item(NAME(m_wmove_active)); save_item(NAME(m_vert_retrace_intrq)); save_item(NAME(m_wmove_intrq)); save_item(NAME(m_display_enable_planes)); - save_item(NAME(m_write_enable_plane)); - save_item(NAME(m_read_enable_plane)); save_item(NAME(m_fb_write_enable)); save_item(NAME(m_enable_blink_planes)); save_item(NAME(m_enable_alt_frame)); @@ -50,6 +51,8 @@ void topcat_device::device_start() save_item(NAME(m_read_enable)); save_item(NAME(m_write_enable)); save_item(NAME(m_fb_enable)); + save_item(NAME(m_unknown_reg4a)); + save_item(NAME(m_unknown_reg4c)); } //------------------------------------------------- @@ -71,17 +74,25 @@ READ16_MEMBER(topcat_device::vram_r) if (mem_mask & m_plane_mask << 8) ret |= m_vram[offset*2] ? m_plane_mask << 8 : 0; - + //LOG("%s: %04X: %04X (mask %04X)\n", __FUNCTION__, offset, ret, mem_mask); return ret; } WRITE16_MEMBER(topcat_device::vram_w) { - if (mem_mask & m_plane_mask) - modify_vram_offset(offset * 2 + 1, (data & m_plane_mask)); + if (mem_mask & m_plane_mask) { + bool src = data & m_plane_mask; + bool dst = m_vram[offset * 2 + 1] & m_plane_mask; + execute_rule(src, (replacement_rule_t)((m_pixel_replacement_rule >> 8) & 0x0f), dst); + modify_vram_offset(offset * 2 + 1, dst); + } - if (mem_mask & m_plane_mask << 8) - modify_vram_offset(offset * 2, (data & m_plane_mask << 8)); + if (mem_mask & (m_plane_mask << 8)) { + bool src = data & (m_plane_mask << 8); + bool dst = m_vram[offset * 2] & m_plane_mask; + execute_rule(src, (replacement_rule_t)((m_pixel_replacement_rule >> 8) & 0x0f), dst); + modify_vram_offset(offset * 2, dst); + } } void topcat_device::get_cursor_pos(int &startx, int &starty, int &endx, int &endy) @@ -218,6 +229,12 @@ void topcat_device::window_move() } } +void topcat_device::update_int() +{ + LOG("%s: wmove %02x retrace %02x\n", __FUNCTION__, m_wmove_intrq, m_vert_retrace_intrq); + m_int_write_func((m_wmove_intrq || m_vert_retrace_intrq) ? ASSERT_LINE : CLEAR_LINE); +} + READ16_MEMBER(topcat_device::ctrl_r) { if (!m_read_enable) @@ -233,23 +250,35 @@ READ16_MEMBER(topcat_device::ctrl_r) break; case TOPCAT_REG_VERT_RETRACE_INTRQ: ret = m_vert_retrace_intrq; + m_vert_retrace_intrq = 0; + update_int(); break; case TOPCAT_REG_WMOVE_INTRQ: ret = m_wmove_intrq; + m_wmove_intrq = 0; + update_int(); break; case TOPCAT_REG_DISPLAY_PLANE_ENABLE: ret = m_display_enable_planes; break; case TOPCAT_REG_WRITE_ENABLE_PLANE: - ret = m_write_enable_plane; + ret = m_write_enable ? (m_plane_mask << 8) : 0; break; case TOPCAT_REG_READ_ENABLE_PLANE: - ret = m_read_enable_plane; + ret = m_read_enable ? (m_plane_mask << 8) : 0; break; case TOPCAT_REG_FB_WRITE_ENABLE: ret = m_fb_write_enable; break; + case TOPCAT_REG_WMOVE_IE: + ret = m_unknown_reg4a; + break; + case TOPCAT_REG_VBLANK_IE: + ret = m_unknown_reg4c; + break; case TOPCAT_REG_START_WMOVE: + m_wmove_intrq = 0; + update_int(); ret = 0; break; case TOPCAT_REG_ENABLE_BLINK_PLANES: @@ -285,6 +314,15 @@ READ16_MEMBER(topcat_device::ctrl_r) case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT: ret = m_block_mover_pixel_height; break; + case TOPCAT_REG_CURSOR_X_POS: + ret = m_cursor_x_pos; + break; + case TOPCAT_REG_CURSOR_Y_POS: + ret = m_cursor_y_pos; + break; + case TOPCAT_REG_CURSOR_WIDTH: + ret = m_cursor_width; + break; default: logerror("unknown register read %02x\n", offset); return space.unmap(); @@ -311,15 +349,17 @@ WRITE16_MEMBER(topcat_device::ctrl_w) switch (offset) { case TOPCAT_REG_VBLANK: - m_vblank = data & 0xff; + m_vblank = data; break; case TOPCAT_REG_WMOVE_ACTIVE: break; case TOPCAT_REG_VERT_RETRACE_INTRQ: - m_vert_retrace_intrq = data; + m_vert_retrace_intrq = 0; + update_int(); break; case TOPCAT_REG_WMOVE_INTRQ: - m_wmove_intrq = data; + m_wmove_intrq = 0; + update_int(); break; case TOPCAT_REG_DISPLAY_PLANE_ENABLE: m_display_enable_planes = data; @@ -327,9 +367,22 @@ WRITE16_MEMBER(topcat_device::ctrl_w) case TOPCAT_REG_FB_WRITE_ENABLE: m_fb_write_enable = data; break; - + case TOPCAT_REG_WMOVE_IE: + m_unknown_reg4a = data; + m_wmove_intrq = 0; + update_int(); + break; + case TOPCAT_REG_VBLANK_IE: + m_unknown_reg4c = data; + m_vert_retrace_intrq = 0; + update_int(); + break; case TOPCAT_REG_START_WMOVE: window_move(); + if (m_unknown_reg4a) { + m_wmove_intrq = m_plane_mask << 8; + update_int(); + } break; case TOPCAT_REG_ENABLE_BLINK_PLANES: m_enable_blink_planes = data; @@ -338,10 +391,10 @@ WRITE16_MEMBER(topcat_device::ctrl_w) m_enable_alt_frame = data; break; case TOPCAT_REG_PIXEL_REPLACE_RULE: - m_pixel_replacement_rule = data; + m_pixel_replacement_rule = data | (data >> 8); break; case TOPCAT_REG_MOVE_REPLACE_RULE: - m_move_replacement_rule = data; + m_move_replacement_rule = data | (data >> 8); break; case TOPCAT_REG_SOURCE_X_PIXEL: m_source_x_pixel = data; @@ -366,15 +419,40 @@ WRITE16_MEMBER(topcat_device::ctrl_w) break; case TOPCAT_REG_CURSOR_X_POS: update_cursor(data, m_cursor_y_pos, m_cursor_plane_enable, m_cursor_width); + m_cursor_x_pos = data; break; case TOPCAT_REG_CURSOR_Y_POS: update_cursor(m_cursor_x_pos, data, m_cursor_plane_enable, m_cursor_width); + m_cursor_y_pos = data; break; case TOPCAT_REG_CURSOR_WIDTH: update_cursor(m_cursor_x_pos, m_cursor_y_pos, m_cursor_plane_enable, data); + m_cursor_width = data; break; default: logerror("unknown register: %02X = %04x\n", offset, data, mem_mask); break; } } + +WRITE_LINE_MEMBER(topcat_device::vblank_w) +{ + if (state) { + m_vblank |= (m_plane_mask << 8); + if (m_unknown_reg4c) { + m_vert_retrace_intrq = (m_plane_mask << 8); + update_int(); + } + } else { + m_vblank &= ~(m_plane_mask << 8); + } +} + +bool topcat_device::plane_enabled() +{ + if (!((m_display_enable_planes >> 8) & m_plane_mask)) + return false; + if ((m_enable_blink_planes & m_plane_mask) && !m_cursor_state) + return false; + return true; +} |