mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +03:00
mc6845: improve the cursor emulation
Implements partial cursors.
This commit is contained in:
parent
6bf0a5c8bb
commit
b88b6693a5
@ -692,6 +692,42 @@ bool mc6845_device::match_line()
|
||||
}
|
||||
|
||||
|
||||
bool mc6845_device::check_cursor_visible(uint16_t ra, uint16_t line_addr)
|
||||
{
|
||||
if (!m_cursor_state)
|
||||
return false;
|
||||
|
||||
if ((m_cursor_addr < line_addr) ||
|
||||
(m_cursor_addr >= (line_addr + m_horiz_disp)))
|
||||
{
|
||||
// Not a cursor character line.
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t cursor_start_ras = m_cursor_start_ras & 0x1f;
|
||||
|
||||
if (cursor_start_ras > m_max_ras_addr)
|
||||
{
|
||||
// No cursor possible.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cursor_start_ras <= m_cursor_end_ras)
|
||||
{
|
||||
if (m_cursor_end_ras > m_max_ras_addr)
|
||||
{
|
||||
// Full cursor.
|
||||
return true;
|
||||
}
|
||||
// Cursor from start to end inclusive.
|
||||
return (ra >= cursor_start_ras) && (ra <= m_cursor_end_ras);
|
||||
}
|
||||
|
||||
// Otherwise cursor_start_ras > m_cursor_end_ras giving a split cursor.
|
||||
return (ra <= m_cursor_end_ras) || (ra >= cursor_start_ras);
|
||||
}
|
||||
|
||||
|
||||
void mc6845_device::handle_line_timer()
|
||||
{
|
||||
bool new_vsync = m_vsync;
|
||||
@ -776,11 +812,7 @@ void mc6845_device::handle_line_timer()
|
||||
m_de_off_timer->adjust(cclks_to_attotime(m_horiz_disp));
|
||||
|
||||
/* Is cursor visible on this line? */
|
||||
if ( m_cursor_state &&
|
||||
(m_raster_counter >= (m_cursor_start_ras & 0x1f)) &&
|
||||
(m_raster_counter <= m_cursor_end_ras) &&
|
||||
(m_cursor_addr >= m_line_address) &&
|
||||
(m_cursor_addr < (m_line_address + m_horiz_disp)) )
|
||||
if (check_cursor_visible(m_raster_counter, m_line_address))
|
||||
{
|
||||
m_cursor_x = m_cursor_addr - m_line_address;
|
||||
|
||||
@ -969,14 +1001,12 @@ uint8_t mc6845_device::draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangl
|
||||
/* compute the current raster line */
|
||||
uint8_t ra = y % (m_max_ras_addr + (MODE_INTERLACE_AND_VIDEO ? m_interlace_adjust : m_noninterlace_adjust));
|
||||
|
||||
/* check if the cursor is visible and is on this scanline */
|
||||
int cursor_visible = m_cursor_state &&
|
||||
(ra >= (m_cursor_start_ras & 0x1f)) &&
|
||||
(ra <= m_cursor_end_ras) &&
|
||||
(m_cursor_addr >= m_current_disp_addr) &&
|
||||
(m_cursor_addr < (m_current_disp_addr + m_horiz_disp));
|
||||
// Check if the cursor is visible and is on this scanline.
|
||||
int cursor_visible = check_cursor_visible(ra, m_current_disp_addr);
|
||||
|
||||
/* compute the cursor X position, or -1 if not visible */
|
||||
// Compute the cursor X position, or -1 if not visible. This position
|
||||
// is in units of characters and is relative to the start of the
|
||||
// displayable area, not relative to the screen bitmap origin.
|
||||
int8_t cursor_x = cursor_visible ? (m_cursor_addr - m_current_disp_addr) : -1;
|
||||
int de = (y < m_max_visible_y) ? 1 : 0;
|
||||
int vbp = m_vert_pix_total - m_vsync_off_pos;
|
||||
|
@ -235,6 +235,7 @@ protected:
|
||||
void set_vsync(int state);
|
||||
void set_cur(int state);
|
||||
bool match_line();
|
||||
bool check_cursor_visible(uint16_t ra, uint16_t line_addr);
|
||||
void handle_line_timer();
|
||||
virtual void update_cursor_state();
|
||||
virtual uint8_t draw_scanline(int y, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
@ -79,11 +79,9 @@ public:
|
||||
void kaypro_map(address_map &map);
|
||||
void kayproii_io(address_map &map);
|
||||
private:
|
||||
void mc6845_cursor_configure();
|
||||
void mc6845_screen_configure();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
uint8_t m_mc6845_cursor[16];
|
||||
uint8_t m_mc6845_reg[32];
|
||||
uint8_t m_mc6845_ind;
|
||||
uint8_t m_framecnt;
|
||||
|
@ -145,7 +145,7 @@ MC6845_UPDATE_ROW( kaypro_state::kaypro484_update_row )
|
||||
for (x = 0; x < x_count; x++) // for each character
|
||||
{
|
||||
uint8_t inv=0;
|
||||
// if (x == cursor_x) inv=0xff; /* uncomment when mame fixed */
|
||||
if (x == cursor_x) inv=0xff;
|
||||
uint16_t mem = (ma + x) & 0x7ff;
|
||||
uint8_t chr = m_p_videoram[mem];
|
||||
uint8_t attr = m_p_videoram[mem | 0x800];
|
||||
@ -177,10 +177,6 @@ MC6845_UPDATE_ROW( kaypro_state::kaypro484_update_row )
|
||||
if ( (BIT(attr, 2)) & (BIT(m_framecnt, 3)) )
|
||||
fg = bg;
|
||||
|
||||
/* process cursor */
|
||||
if (x == cursor_x)
|
||||
inv ^= m_mc6845_cursor[ra];
|
||||
|
||||
/* get pattern of pixels for that character scanline */
|
||||
if ( (ra == 15) & (BIT(attr, 3)) ) /* underline */
|
||||
gfx = 0xff;
|
||||
@ -201,41 +197,6 @@ MC6845_UPDATE_ROW( kaypro_state::kaypro484_update_row )
|
||||
|
||||
/************************************* MC6845 SUPPORT ROUTINES ***************************************/
|
||||
|
||||
/* The 6845 can produce a variety of cursor shapes - all are emulated here - remove when mame fixed */
|
||||
void kaypro_state::mc6845_cursor_configure()
|
||||
{
|
||||
uint8_t i,curs_type=0,r9,r10,r11;
|
||||
|
||||
/* curs_type holds the general cursor shape to be created
|
||||
0 = no cursor
|
||||
1 = partial cursor (only shows on a block of scan lines)
|
||||
2 = full cursor
|
||||
3 = two-part cursor (has a part at the top and bottom with the middle blank) */
|
||||
|
||||
for ( i = 0; i < ARRAY_LENGTH(m_mc6845_cursor); i++) m_mc6845_cursor[i] = 0; // prepare cursor by erasing old one
|
||||
|
||||
r9 = m_mc6845_reg[9]; // number of scan lines - 1
|
||||
r10 = m_mc6845_reg[10] & 0x1f; // cursor start line = last 5 bits
|
||||
r11 = m_mc6845_reg[11]+1; // cursor end line incremented to suit for-loops below
|
||||
|
||||
/* decide the curs_type by examining the registers */
|
||||
if (r10 < r11) curs_type=1; // start less than end, show start to end
|
||||
else
|
||||
if (r10 == r11) curs_type=2; // if equal, show full cursor
|
||||
else curs_type=3; // if start greater than end, it's a two-part cursor
|
||||
|
||||
if ((r11 - 1) > r9) curs_type=2; // if end greater than scan-lines, show full cursor
|
||||
if (r10 > r9) curs_type=0; // if start greater than scan-lines, then no cursor
|
||||
if (r11 > 16) r11=16; // truncate 5-bit register to fit our 4-bit hardware
|
||||
|
||||
/* create the new cursor */
|
||||
if (curs_type > 1) for (i = 0;i < ARRAY_LENGTH(m_mc6845_cursor);i++) m_mc6845_cursor[i]=0xff; // turn on full cursor
|
||||
|
||||
if (curs_type == 1) for (i = r10;i < r11;i++) m_mc6845_cursor[i]=0xff; // for each line that should show, turn on that scan line
|
||||
|
||||
if (curs_type == 3) for (i = r11; i < r10;i++) m_mc6845_cursor[i]=0; // now take a bite out of the middle
|
||||
}
|
||||
|
||||
/* Resize the screen within the limits of the hardware. Expand the image to fill the screen area.
|
||||
Standard screen is 640 x 400 = 0x7d0 bytes. */
|
||||
|
||||
@ -280,9 +241,6 @@ WRITE8_MEMBER( kaypro_state::kaypro484_register_w )
|
||||
if ((m_mc6845_ind == 1) || (m_mc6845_ind == 6) || (m_mc6845_ind == 9))
|
||||
mc6845_screen_configure(); /* adjust screen size */
|
||||
|
||||
if ((m_mc6845_ind > 8) && (m_mc6845_ind < 12))
|
||||
mc6845_cursor_configure(); /* adjust cursor shape - remove when mame fixed */
|
||||
|
||||
if ((m_mc6845_ind > 17) && (m_mc6845_ind < 20))
|
||||
m_mc6845_video_address = m_mc6845_reg[19] | ((m_mc6845_reg[18] & 0x3f) << 8); /* internal ULA address */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user