diff --git a/src/devices/bus/hp_dio/hp98543.cpp b/src/devices/bus/hp_dio/hp98543.cpp index 25a98439351..b43a4734e0b 100644 --- a/src/devices/bus/hp_dio/hp98543.cpp +++ b/src/devices/bus/hp_dio/hp98543.cpp @@ -154,10 +154,24 @@ WRITE16_MEMBER(dio16_98543_device::vram_w) uint32_t dio16_98543_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { + int startx[TOPCAT_COUNT], starty[TOPCAT_COUNT]; + int endx[TOPCAT_COUNT], endy[TOPCAT_COUNT]; + + for (int i = 0; i < TOPCAT_COUNT; i++) + m_topcat[i]->get_cursor_pos(&startx[i], &starty[i], &endx[i], &endy[i]); + for (int y = 0; y < m_v_pix; y++) { uint32_t *scanline = &bitmap.pix32(y); - for (int x = 0; x < m_h_pix; x++) - *scanline++ = m_nereid->map_color(m_vram[y * m_h_pix + x]); + + for (int x = 0; x < m_h_pix; x++) { + uint8_t tmp = m_vram[y * m_h_pix + x]; + for (int i = 0; i < TOPCAT_COUNT; i++) { + if (y >= starty[i] && y <= endy[i] && x >= startx[i] && x <= endx[i]) { + tmp |= 1 << i; + } + } + *scanline++ = m_nereid->map_color(tmp); + } } return 0; } diff --git a/src/devices/bus/hp_dio/hp98543.h b/src/devices/bus/hp_dio/hp98543.h index 0f7110f3787..aa78139ae83 100644 --- a/src/devices/bus/hp_dio/hp98543.h +++ b/src/devices/bus/hp_dio/hp98543.h @@ -27,7 +27,9 @@ public: DECLARE_READ16_MEMBER(vram_r); DECLARE_WRITE16_MEMBER(vram_w); - required_device_array m_topcat; + static constexpr int TOPCAT_COUNT = 4; + + required_device_array m_topcat; required_device m_nereid; uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); diff --git a/src/devices/bus/hp_dio/hp98544.cpp b/src/devices/bus/hp_dio/hp98544.cpp index db790a89977..5112ace8781 100644 --- a/src/devices/bus/hp_dio/hp98544.cpp +++ b/src/devices/bus/hp_dio/hp98544.cpp @@ -128,11 +128,19 @@ WRITE16_MEMBER(dio16_98544_device::rom_w) uint32_t dio16_98544_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - for (int y = 0; y < 768; y++) { - uint32_t *scanline = &bitmap.pix32(y); - for (int x = 0; x < 1024; x++) - *scanline++ = m_vram[y * 1024 + x] ? rgb_t(255,255,255) : rgb_t(0, 0, 0); - } - return 0; + int startx, starty, endx, endy; + + m_topcat->get_cursor_pos(&startx, &starty, &endx, &endy); + + for (int y = 0; y < m_v_pix; y++) { + uint32_t *scanline = &bitmap.pix32(y); + for (int x = 0; x < 1024; x++) { + uint8_t tmp = m_vram[y * m_h_pix + x]; + if (y >= starty && y <= endy && x >= startx && x <= endx) + tmp |= 0xff; + *scanline++ = tmp ? rgb_t(255,255,255) : rgb_t(0, 0, 0); + } + } + return 0; } diff --git a/src/devices/bus/hp_dio/hp98544.h b/src/devices/bus/hp_dio/hp98544.h index c153cfcbcc3..91139bc5dc5 100644 --- a/src/devices/bus/hp_dio/hp98544.h +++ b/src/devices/bus/hp_dio/hp98544.h @@ -40,6 +40,10 @@ public: virtual const tiny_rom_entry *device_rom_region() const override; virtual space_config_vector memory_space_config() const override; private: + + static constexpr int m_v_pix = 768; + static constexpr int m_h_pix = 1024; + const address_space_config m_space_config; void map(address_map &map); diff --git a/src/devices/video/nereid.cpp b/src/devices/video/nereid.cpp index fede953c277..c1c51c8ddbb 100644 --- a/src/devices/video/nereid.cpp +++ b/src/devices/video/nereid.cpp @@ -42,7 +42,7 @@ READ16_MEMBER(nereid_device::ctrl_r) { LOG("NEREID ctrl_r: %02X\n", offset); - switch(offset) { + switch(offset & 0x7f) { case NEREID_BUSY: return 0; case NEREID_RED_DATA: @@ -67,7 +67,7 @@ WRITE16_MEMBER(nereid_device::ctrl_w) { LOG("NEREID: ctrl_w %02X = %02X\n", offset, data); data &= 0xff; - switch(offset) { + switch(offset & 0x7f) { case NEREID_RED_DATA: m_red = data; break; diff --git a/src/devices/video/topcat.cpp b/src/devices/video/topcat.cpp index d4f4188623e..f1e9f6c5399 100644 --- a/src/devices/video/topcat.cpp +++ b/src/devices/video/topcat.cpp @@ -35,7 +35,7 @@ void topcat_device::device_start() save_item(NAME(m_fb_write_enable)); save_item(NAME(m_enable_blink_planes)); save_item(NAME(m_enable_alt_frame)); - save_item(NAME(m_cursor_ctrl)); + save_item(NAME(m_cursor_plane_enable)); save_item(NAME(m_move_replacement_rule)); save_item(NAME(m_pixel_replacement_rule)); save_item(NAME(m_source_x_pixel)); @@ -83,30 +83,33 @@ WRITE16_MEMBER(topcat_device::vram_w) modify_vram_offset(offset * 2, (data & m_plane_mask << 8)); } +void topcat_device::get_cursor_pos(int *startx, int *starty, int *endx, int *endy) +{ + if (m_cursor_state && ((m_cursor_plane_enable >> 8) & m_plane_mask)) { + *startx = m_cursor_x_pos; + *starty = m_cursor_y_pos; + *endx = m_cursor_x_pos + m_cursor_width; + *endy = m_cursor_y_pos; + + } else { + *startx = 0; + *starty = 0; + *endx = 0; + *endy = 0; + } +} + TIMER_CALLBACK_MEMBER(topcat_device::cursor_callback) { m_cursor_timer->adjust(attotime::from_hz(5)); m_cursor_state ^= true; - - if (m_cursor_ctrl & m_plane_mask) { - for(int i = 0; i < m_cursor_width; i++) { - modify_vram(m_cursor_x_pos+i, m_cursor_y_pos, m_cursor_state); - modify_vram(m_cursor_x_pos+i, m_cursor_y_pos-1, m_cursor_state); - modify_vram(m_cursor_x_pos+i, m_cursor_y_pos-2, m_cursor_state); - } - } } -void topcat_device::update_cursor(int x, int y, uint8_t ctrl, uint8_t width) +void topcat_device::update_cursor(int x, int y, uint16_t ctrl, uint8_t width) { - for(int i = 0; i < m_cursor_width; i++) { - modify_vram(m_cursor_x_pos+i, m_cursor_y_pos, false); - modify_vram(m_cursor_x_pos+i, m_cursor_y_pos-1, false); - modify_vram(m_cursor_x_pos+i, m_cursor_y_pos-2, false); - } m_cursor_x_pos = (std::min)(x, m_fb_width - m_cursor_width); m_cursor_y_pos = (std::max)((std::min)(y, m_fb_height), 2); - m_cursor_ctrl = ctrl; + m_cursor_plane_enable = ctrl; m_cursor_width = width; } @@ -166,16 +169,52 @@ void topcat_device::execute_rule(bool src, replacement_rule_t rule, bool &dst) void topcat_device::window_move(void) { - if (!m_fb_write_enable) + int line, endline, lineincr; + int startcolumn, endcolumn, columnincr; + + if (!((m_fb_write_enable >> 8) & m_plane_mask)) return; - for(int line = 0; line < m_block_mover_pixel_height; line++) { - for(int column = 0; column < m_block_mover_pixel_width; column++) { + LOG("WINDOWMOVE: %3ux%3u -> %3ux%3u / %3ux%3u rule %x\n", + m_source_x_pixel, + m_source_y_pixel, + m_dst_x_pixel, + m_dst_y_pixel, + m_block_mover_pixel_width, + m_block_mover_pixel_height, + m_move_replacement_rule); + + if (m_dst_y_pixel > m_source_y_pixel) { + /* move down */ + line = m_block_mover_pixel_height-1; + endline = -1; + lineincr = -1; + } else { + /* move up */ + line = 0; + endline = m_block_mover_pixel_height; + lineincr = 1; + } + + if (m_dst_x_pixel > m_source_x_pixel) { + /* move right */ + startcolumn = m_block_mover_pixel_width-1; + endcolumn = -1; + columnincr = -1; + } else { + /* move left */ + startcolumn = 0; + endcolumn = m_block_mover_pixel_width; + columnincr = 1; + + } + + for(;line != endline; line += lineincr) { + for(int column = startcolumn; column != endcolumn; column += columnincr) { bool src = get_vram_pixel(m_source_x_pixel + column, m_source_y_pixel + line); bool dst = get_vram_pixel(m_dst_x_pixel + column, m_dst_y_pixel + line); -// execute_rule(src, (replacement_rule_t)((m_move_replacement_rule >> 4) & 0x0f), &dst); execute_rule(src, (replacement_rule_t)(m_move_replacement_rule & 0x0f), dst); modify_vram(m_dst_x_pixel + column, m_dst_y_pixel + line, dst); } @@ -184,7 +223,6 @@ void topcat_device::window_move(void) READ16_MEMBER(topcat_device::ctrl_r) { - uint16_t ret = 0xffff; if (!m_read_enable) @@ -224,8 +262,8 @@ READ16_MEMBER(topcat_device::ctrl_r) case TOPCAT_REG_ENABLE_ALT_FRAME: ret = m_enable_alt_frame; break; - case TOPCAT_REG_CURSOR_CNTL: - ret = m_cursor_ctrl; + case TOPCAT_REG_CURSOR_PLANE_ENABLE: + ret = m_cursor_plane_enable; break; case TOPCAT_REG_PIXEL_REPLACE_RULE: ret = m_pixel_replacement_rule; @@ -260,27 +298,21 @@ READ16_MEMBER(topcat_device::ctrl_r) WRITE16_MEMBER(topcat_device::ctrl_w) { - if (mem_mask == 0xff00) - data >>= 8; - if (mem_mask == 0x00ff) { - logerror("%s: write ignored: %d\n", __FUNCTION__, offset); - return; - } + data &= mem_mask; - if (offset == TOPCAT_REG_WRITE_ENABLE_PLANE && ((mem_mask & 0xff) == 0xff)) { - m_write_enable = !(data & m_plane_mask); + if (offset == TOPCAT_REG_WRITE_ENABLE_PLANE) { + m_write_enable = (data >> 8) & m_plane_mask; return; } if (offset == TOPCAT_REG_READ_ENABLE_PLANE) { - m_read_enable = !(data & m_plane_mask); + m_read_enable = (data >> 8) & m_plane_mask; return; } - if (!m_write_enable) { + if (!m_write_enable) return; - } switch(offset) { case TOPCAT_REG_VBLANK: @@ -298,8 +330,9 @@ WRITE16_MEMBER(topcat_device::ctrl_w) m_display_enable_planes = data; break; case TOPCAT_REG_FB_WRITE_ENABLE: - m_fb_write_enable = data & m_plane_mask; + m_fb_write_enable = data; break; + case TOPCAT_REG_START_WMOVE: window_move(); break; @@ -313,7 +346,6 @@ WRITE16_MEMBER(topcat_device::ctrl_w) m_pixel_replacement_rule = data; break; case TOPCAT_REG_MOVE_REPLACE_RULE: - m_move_replacement_rule = data; break; case TOPCAT_REG_SOURCE_X_PIXEL: @@ -334,17 +366,17 @@ WRITE16_MEMBER(topcat_device::ctrl_w) case TOPCAT_REG_BLOCK_MOVER_PIXEL_HEIGHT: m_block_mover_pixel_height = data; break; - case TOPCAT_REG_CURSOR_CNTL: + case TOPCAT_REG_CURSOR_PLANE_ENABLE: 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); + update_cursor(data, m_cursor_y_pos, m_cursor_plane_enable, m_cursor_width); break; case TOPCAT_REG_CURSOR_Y_POS: - update_cursor(m_cursor_x_pos, data, m_cursor_ctrl, m_cursor_width); + update_cursor(m_cursor_x_pos, data, m_cursor_plane_enable, m_cursor_width); break; case TOPCAT_REG_CURSOR_WIDTH: - update_cursor(m_cursor_x_pos, m_cursor_y_pos, m_cursor_ctrl, data); + update_cursor(m_cursor_x_pos, m_cursor_y_pos, m_cursor_plane_enable, data); break; default: logerror("unknown register: %02X = %04x\n", offset, data, mem_mask); diff --git a/src/devices/video/topcat.h b/src/devices/video/topcat.h index f7bf73655c6..114d4bc208a 100644 --- a/src/devices/video/topcat.h +++ b/src/devices/video/topcat.h @@ -22,6 +22,7 @@ public: void set_fb_width(int _pixels) { m_fb_width = _pixels; } void set_fb_height(int _pixels) { m_fb_height = _pixels; } void set_planemask(int _mask) { m_plane_mask = _mask; } + void get_cursor_pos(int *startx, int *starty, int *endx, int *endy); TIMER_CALLBACK_MEMBER(cursor_callback); @@ -31,6 +32,7 @@ public: DECLARE_WRITE16_MEMBER(ctrl_w); void topcat_mem(address_map &map); + protected: topcat_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -70,7 +72,7 @@ private: TOPCAT_REG_START_WMOVE=0x4e, TOPCAT_REG_ENABLE_BLINK_PLANES=0x50, TOPCAT_REG_ENABLE_ALT_FRAME=0x54, - TOPCAT_REG_CURSOR_CNTL=0x56, + TOPCAT_REG_CURSOR_PLANE_ENABLE=0x56, TOPCAT_REG_PIXEL_REPLACE_RULE=0x75, TOPCAT_REG_MOVE_REPLACE_RULE=0x77, TOPCAT_REG_SOURCE_X_PIXEL=0x79, @@ -87,7 +89,7 @@ private: void window_move(void); void execute_rule(bool src, replacement_rule_t rule, bool &dst); - void update_cursor(int x, int y, uint8_t ctrl, uint8_t width); + void update_cursor(int x, int y, uint16_t ctrl, uint8_t width); void modify_vram(int x, int y, bool state) { if (state) @@ -114,12 +116,12 @@ private: uint8_t m_display_enable_planes; bool m_write_enable_plane; bool m_read_enable_plane; - bool m_fb_write_enable; - uint8_t m_enable_blink_planes; - uint8_t m_enable_alt_frame; - uint8_t m_cursor_ctrl; - uint8_t m_move_replacement_rule; - uint8_t m_pixel_replacement_rule; + uint16_t m_fb_write_enable; + uint16_t m_enable_blink_planes; + uint16_t m_enable_alt_frame; + uint16_t m_cursor_plane_enable; + uint16_t m_move_replacement_rule; + uint16_t m_pixel_replacement_rule; uint16_t m_source_x_pixel; uint16_t m_source_y_pixel; uint16_t m_dst_x_pixel;