mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Topcat improvements (#3663)
* topcat: fix register accesses * nereid: mask register address bits * topcat: don't override contents before window move depending on the direction of the window move, we must start at the other end with move, otherwise we overwrite the data before it is moved. Signed-off-by: Sven Schnelle <svens@stackframe.org> * topcat: Fix cursor handling Old cursor handling hat a few problems: - Changed VRAM contents which doesn't happen on real hardware - Destroyed Image content on the line where the cursor is show - Window mover copied the cursor Signed-off-by: Sven Schnelle <svens@stackframe.org> * fix spacing Signed-off-by: Sven Schnelle <svens@stackframe.org>
This commit is contained in:
parent
ec51f04e72
commit
e7c798da50
@ -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;
|
||||
}
|
||||
|
@ -27,7 +27,9 @@ public:
|
||||
DECLARE_READ16_MEMBER(vram_r);
|
||||
DECLARE_WRITE16_MEMBER(vram_w);
|
||||
|
||||
required_device_array<topcat_device, 4> m_topcat;
|
||||
static constexpr int TOPCAT_COUNT = 4;
|
||||
|
||||
required_device_array<topcat_device, TOPCAT_COUNT> m_topcat;
|
||||
required_device<nereid_device> m_nereid;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user