summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/hp_dio/hp98544.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/hp_dio/hp98544.cpp')
-rw-r--r--src/devices/bus/hp_dio/hp98544.cpp262
1 files changed, 260 insertions, 2 deletions
diff --git a/src/devices/bus/hp_dio/hp98544.cpp b/src/devices/bus/hp_dio/hp98544.cpp
index 96b464a9f86..c0b2b8177b7 100644
--- a/src/devices/bus/hp_dio/hp98544.cpp
+++ b/src/devices/bus/hp_dio/hp98544.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:R. Belmont
+// copyright-holders:R. Belmont, Sven Schnelle
/***************************************************************************
HP98544 high-resolution monochrome board
@@ -85,6 +85,10 @@ void dio16_98544_device::device_start()
write16_delegate(FUNC(dio16_98544_device::vram_w), this));
m_dio->install_memory(0x560000, 0x563fff, read16_delegate(FUNC(dio16_98544_device::rom_r), this),
write16_delegate(FUNC(dio16_98544_device::rom_w), this));
+ m_dio->install_memory(0x564000, 0x567fff, read16_delegate(FUNC(dio16_98544_device::ctrl_r), this),
+ write16_delegate(FUNC(dio16_98544_device::ctrl_w), this));
+ m_cursor_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(dio16_98544_device::cursor_callback),this));
+ m_cursor_timer->adjust(attotime::from_hz(3));
}
//-------------------------------------------------
@@ -97,6 +101,34 @@ void dio16_98544_device::device_reset()
m_palette[1] = rgb_t(255, 255, 255);
m_palette[0] = rgb_t(0, 0, 0);
+ m_pixel_replacement_rule = TOPCAT_REPLACE_RULE_SRC;
+}
+
+TIMER_CALLBACK_MEMBER(dio16_98544_device::cursor_callback)
+{
+ m_cursor_timer->adjust(attotime::from_hz(5));
+ m_cursor_state ^= true;
+
+ if (m_cursor_ctrl & 0x02) {
+ for(int i = 0; i < m_cursor_width; i++) {
+ m_vram[(m_cursor_y_pos * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
+ m_vram[((m_cursor_y_pos-1) * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
+ m_vram[((m_cursor_y_pos-2) * 512) + (m_cursor_x_pos + i)/2] = m_cursor_state ? 0xffff : 0;
+ }
+ }
+}
+
+void dio16_98544_device::update_cursor(int x, int y, uint8_t ctrl, uint8_t width)
+{
+ for(int i = 0; i < m_cursor_width; i++) {
+ m_vram[(m_cursor_y_pos * 512) + (m_cursor_x_pos + i)/2] = 0;
+ m_vram[((m_cursor_y_pos-1) * 512) + (m_cursor_x_pos + i)/2] = 0;
+ m_vram[((m_cursor_y_pos-2) * 512) + (m_cursor_x_pos + i)/2] = 0;
+ }
+ m_cursor_x_pos = x;
+ m_cursor_y_pos = y;
+ m_cursor_ctrl = ctrl;
+ m_cursor_width = width;
}
READ16_MEMBER(dio16_98544_device::vram_r)
@@ -106,6 +138,7 @@ READ16_MEMBER(dio16_98544_device::vram_r)
WRITE16_MEMBER(dio16_98544_device::vram_w)
{
+// execute_rule(data, (replacement_rule_t)m_pixel_replacement_rule, &data);
COMBINE_DATA(&m_vram[offset]);
}
@@ -117,9 +150,234 @@ READ16_MEMBER(dio16_98544_device::rom_r)
// the video chip registers live here, so these writes are valid
WRITE16_MEMBER(dio16_98544_device::rom_w)
{
- printf("rom_w: %02x at %x (mask %04x)\n", data, offset, mem_mask);
}
+void dio16_98544_device::execute_rule(uint16_t src, replacement_rule_t rule, uint16_t *dst)
+{
+ switch(rule & 0x0f) {
+ case TOPCAT_REPLACE_RULE_CLEAR:
+ *dst = 0;
+ break;
+ case TOPCAT_REPLACE_RULE_SRC_AND_DST:
+ *dst &= src;
+ break;
+ case TOPCAT_REPLACE_RULE_SRC_AND_NOT_DST:
+ *dst = ~(*dst) & src;
+ break;
+ case TOPCAT_REPLACE_RULE_SRC:
+ *dst = src;
+ break;
+ case TOPCAT_REPLACE_RULE_NOT_SRC_AND_DST:
+ *dst &= ~src;
+ break;
+ case TOPCAT_REPLACE_RULE_NOP:
+ break;
+ case TOPCAT_REPLACE_RULE_SRC_XOR_DST:
+ *dst ^= src;
+ break;
+ case TOPCAT_REPLACE_RULE_SRC_OR_DST:
+ *dst |= src;
+ break;
+ case TOPCAT_REPLACE_RULE_NOT_SRC_AND_NOT_DST:
+ *dst = ~(*dst) & ~src;
+ break;
+ case TOPCAT_REPLACE_RULE_NOT_SRC_XOR_DST:
+ *dst ^= ~src;
+ break;
+ case TOPCAT_REPLACE_RULE_NOT_DST:
+ *dst ^= 0xffff;
+ break;
+ case TOPCAT_REPLACE_RULE_SRC_OR_NOT_DST:
+ *dst = src | ~(*dst);
+ break;
+ case TOPCAT_REPLACE_RULE_NOT_SRC:
+ *dst = ~src;
+ break;
+ case TOPCAT_REPLACE_RULE_NOT_SRC_OR_DST:
+ *dst = ~src | *dst;
+ break;
+ case TOPCAT_REPLACE_RULE_NOT_SRC_OR_NOT_DST:
+ *dst = ~src | ~(*dst);
+ break;
+ case TOPCAT_REPLACE_RULE_SET:
+ *dst = 0xffff;
+ break;
+
+ }
+}
+
+void dio16_98544_device::window_move(void)
+{
+ for(int line = 0; line < m_block_mover_pixel_height; line++) {
+ for(int column = 0; column < m_block_mover_pixel_width; column++) {
+ uint16_t sdata = m_vram[((m_source_y_pixel + line) * 1024 + (m_source_x_pixel + column))/2];
+ uint16_t *ddata = &m_vram[((m_dst_y_pixel + line) * 1024 + (m_dst_x_pixel + column))/2];
+ execute_rule(sdata, (replacement_rule_t)((m_move_replacement_rule >> 4) & 0x0f), ddata);
+ execute_rule(sdata, (replacement_rule_t)(m_move_replacement_rule & 0x0f), ddata);
+ }
+ }
+}
+
+WRITE16_MEMBER(dio16_98544_device::ctrl_w)
+{
+ if (mem_mask == 0xff00)
+ data >>= 8;
+
+ if (mem_mask == 0x00ff) {
+ logerror("%s: write ignored\n", __FUNCTION__);
+ return;
+ }
+
+ switch(offset) {
+ case TOPCAT_REG_VBLANK:
+ m_vblank = data & 0xff;
+ break;
+ case TOPCAT_REG_WMOVE_ACTIVE:
+ break;
+ case TOPCAT_REG_VERT_RETRACE_INTRQ:
+ m_vert_retrace_intrq = data;
+ break;
+ case TOPCAT_REG_WMOVE_INTRQ:
+ m_wmove_intrq = data;
+ break;
+ case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
+ m_display_enable_planes = data;
+ break;
+ case TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE:
+ m_write_enable_plane = data;
+ break;
+ case TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE:
+ m_read_enable_plane = data;
+ break;
+ case TOPCAT_REG_FB_WRITE_ENABLE:
+ m_fb_write_enable = data;
+ break;
+ case TOPCAT_REG_START_WMOVE:
+ window_move();
+ break;
+ case TOPCAT_REG_ENABLE_BLINK_PLANES:
+ logerror("ENABLE_BLINK_PLANES: %04x\n", data);
+ m_enable_blink_planes = data;
+ break;
+ case TOPCAT_REG_ENABLE_ALT_FRAME:
+ logerror("ENABLE_ALT_PLANE: %04x\n", data);
+ m_enable_alt_frame = data;
+ break;
+ case TOPCAT_REG_PIXEL_REPLACE_RULE:
+ logerror("PIXEL RR: data %04X mask %04X\n", data, mem_mask);
+ m_pixel_replacement_rule = data;
+ break;
+ case TOPCAT_REG_MOVE_REPLACE_RULE:
+ logerror("MOVE RR: data %04X mask %04X\n", data, mem_mask);
+ m_move_replacement_rule = data;
+ break;
+ case TOPCAT_REG_SOURCE_X_PIXEL:
+ m_source_x_pixel = data;
+ break;
+ case TOPCAT_REG_SOURCE_Y_PIXEL:
+ m_source_y_pixel = data;
+ break;
+ case TOPCAT_REG_DST_X_PIXEL:
+ m_dst_x_pixel = data;
+ break;
+ case TOPCAT_REG_DST_Y_PIXEL:
+ m_dst_y_pixel = data;
+ break;
+ case TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH:
+ m_block_mover_pixel_width = data;
+ break;
+ case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT:
+ m_block_mover_pixel_height = data;
+ break;
+ case TOPCAT_REG_CURSOR_CNTL:
+ update_cursor(m_cursor_x_pos, m_cursor_y_pos, data, m_cursor_width);
+ break;
+ case TOPCAT_REG_CURSOR_X_POS:
+ update_cursor(data, m_cursor_y_pos, m_cursor_ctrl, m_cursor_width);
+ break;
+ case TOPCAT_REG_CURSOR_Y_POS:
+ update_cursor(m_cursor_x_pos, data, m_cursor_ctrl, m_cursor_width);
+ break;
+ case TOPCAT_REG_CURSOR_WIDTH:
+ update_cursor(m_cursor_x_pos, m_cursor_y_pos, m_cursor_ctrl, data);
+ break;
+ default:
+ logerror("unknown register: %02X = %04x\n", offset, data, mem_mask);
+ break;
+ }
+}
+
+READ16_MEMBER(dio16_98544_device::ctrl_r)
+{
+ uint16_t ret = 0xffff;
+
+ switch(offset) {
+ case TOPCAT_REG_VBLANK:
+ ret = m_vblank;
+ break;
+ case TOPCAT_REG_WMOVE_ACTIVE:
+ ret = m_wmove_active;
+ break;
+ case TOPCAT_REG_VERT_RETRACE_INTRQ:
+ ret = m_vert_retrace_intrq;
+ break;
+ case TOPCAT_REG_WMOVE_INTRQ:
+ ret = m_wmove_intrq;
+ break;
+ case TOPCAT_REG_DISPLAY_PLANE_ENABLE:
+ ret = m_display_enable_planes;
+ break;
+ case TOPCAT_REG_DISPLAY_WRITE_ENABLE_PLANE:
+ ret = m_write_enable_plane;
+ break;
+ case TOPCAT_REG_DISPLAY_READ_ENABLE_PLANE:
+ ret = m_read_enable_plane;
+ break;
+ case TOPCAT_REG_FB_WRITE_ENABLE:
+ ret = m_fb_write_enable;
+ break;
+ case TOPCAT_REG_START_WMOVE:
+ ret = 0;
+ break;
+ case TOPCAT_REG_ENABLE_BLINK_PLANES:
+ ret = m_enable_blink_planes;
+ break;
+ case TOPCAT_REG_ENABLE_ALT_FRAME:
+ ret = m_enable_alt_frame;
+ break;
+ case TOPCAT_REG_CURSOR_CNTL:
+ ret = m_cursor_ctrl;
+ break;
+ case TOPCAT_REG_PIXEL_REPLACE_RULE:
+ ret = m_pixel_replacement_rule;
+ break;
+ case TOPCAT_REG_MOVE_REPLACE_RULE:
+ ret = m_move_replacement_rule;
+ break;
+ case TOPCAT_REG_SOURCE_X_PIXEL:
+ ret = m_source_x_pixel;
+ break;
+ case TOPCAT_REG_SOURCE_Y_PIXEL:
+ ret = m_source_y_pixel;
+ break;
+ case TOPCAT_REG_DST_X_PIXEL:
+ ret = m_dst_x_pixel;
+ break;
+ case TOPCAT_REG_DST_Y_PIXEL:
+ ret = m_dst_y_pixel;
+ break;
+ case TOPCAT_REG_BLOCK_MOVER_PIXEL_WIDTH:
+ ret = m_block_mover_pixel_width;
+ break;
+ case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT:
+ ret = m_block_mover_pixel_height;
+ break;
+ default:
+ logerror("unknown register read %02x\n", offset);
+ break;
+ }
+ return ret;
+}
uint32_t dio16_98544_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
uint32_t *scanline;