summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/topcat.cpp
diff options
context:
space:
mode:
author dxl <41547105+hp9k@users.noreply.github.com>2018-08-31 22:06:05 +0200
committer R. Belmont <rb6502@users.noreply.github.com>2018-08-31 16:06:05 -0400
commit89ae43bfbbbea7353053bacf96c1ca2098c40432 (patch)
treed70b13ba78c5232c11f90797d59d8b4d83c767cb /src/devices/video/topcat.cpp
parentf0b81ff6aa19a97173d9fee5db8729e86dfa1791 (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.cpp108
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;
+}