mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
ega: palette and memory map fixes
This commit is contained in:
parent
ce212a5e9a
commit
ad7cbf9c0a
@ -554,6 +554,7 @@ void isa8_ega_device::device_add_mconfig(machine_config &config)
|
||||
m_crtc_ega->res_out_hsync_callback().set(FUNC(isa8_ega_device::hsync_changed));
|
||||
m_crtc_ega->res_out_vsync_callback().set(FUNC(isa8_ega_device::vsync_changed));
|
||||
m_crtc_ega->res_out_vblank_callback().set(FUNC(isa8_ega_device::vblank_changed));
|
||||
m_crtc_ega->res_out_irq_callback().set([this](int state) { m_isa->irq2_w(state); });
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -636,6 +637,15 @@ void isa8_ega_device::device_start()
|
||||
m_plane[2] = m_videoram + 0x20000;
|
||||
m_plane[3] = m_videoram + 0x30000;
|
||||
|
||||
save_item(STRUCT_MEMBER(m_graphics_controller, index));
|
||||
save_item(STRUCT_MEMBER(m_graphics_controller, data));
|
||||
save_item(STRUCT_MEMBER(m_sequencer, index));
|
||||
save_item(STRUCT_MEMBER(m_sequencer, data));
|
||||
save_item(STRUCT_MEMBER(m_attribute, index));
|
||||
save_item(STRUCT_MEMBER(m_attribute, data));
|
||||
save_item(STRUCT_MEMBER(m_attribute, index_write));
|
||||
save_pointer(NAME(m_vram), 256 * 1024);
|
||||
|
||||
m_isa->install_rom(this, 0xc0000, 0xc3fff, "user2");
|
||||
m_isa->install_device(0x3b0, 0x3bf, read8sm_delegate(*this, FUNC(isa8_ega_device::pc_ega8_3b0_r)), write8sm_delegate(*this, FUNC(isa8_ega_device::pc_ega8_3b0_w)));
|
||||
m_isa->install_device(0x3c0, 0x3cf, read8sm_delegate(*this, FUNC(isa8_ega_device::pc_ega8_3c0_r)), write8sm_delegate(*this, FUNC(isa8_ega_device::pc_ega8_3c0_w)));
|
||||
@ -747,9 +757,9 @@ void isa8_ega_device::install_banks()
|
||||
CRTC_EGA_ROW_UPDATE( isa8_ega_device::ega_update_row )
|
||||
{
|
||||
if (m_video_mode == EGA_MODE_GRAPHICS)
|
||||
pc_ega_graphics(bitmap, cliprect, ma, ra, y, x_count, cursor_x);
|
||||
pc_ega_graphics(bitmap, cliprect, ma, ra, y, x, cursor_x);
|
||||
else if (m_video_mode == EGA_MODE_TEXT)
|
||||
pc_ega_text(bitmap, cliprect, ma, ra, y, x_count, cursor_x);
|
||||
pc_ega_text(bitmap, cliprect, ma, ra, y, x, cursor_x);
|
||||
}
|
||||
|
||||
|
||||
@ -783,31 +793,28 @@ WRITE_LINE_MEMBER( isa8_ega_device::vblank_changed )
|
||||
|
||||
CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics )
|
||||
{
|
||||
uint16_t *p = &bitmap.pix(y);
|
||||
uint16_t *p = &bitmap.pix(y, x * 8);
|
||||
|
||||
LOG("%s: y = %d, x_count = %d, ma = %d, ra = %d\n", FUNCNAME, y, x_count, ma, ra );
|
||||
LOG("%s: y = %d, x = %d, ma = %d, ra = %d\n", FUNCNAME, y, x, ma, ra );
|
||||
|
||||
if ( m_graphics_controller.data[5] & 0x10 )
|
||||
{
|
||||
// Odd/Even mode (CGA compatible)
|
||||
|
||||
for ( int i = 0; i < x_count; i++ )
|
||||
{
|
||||
uint16_t offset = ( ( ma + i ) & 0x1fff ) | ( ( y & 1 ) << 12 );
|
||||
uint8_t data = m_plane[0][offset];
|
||||
uint16_t offset = ( ma & 0x1fff ) | ( ( y & 1 ) << 12 );
|
||||
uint8_t data = m_plane[BIT(m_misc_output, 5) ? 2 : 0][offset];
|
||||
|
||||
*p = m_attribute.data[ ( data >> 6 ) ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ data & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 6 ) ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ data & 0x03 ]; p++;
|
||||
|
||||
data = m_plane[1][offset];
|
||||
data = m_plane[BIT(m_misc_output, 5) ? 3 : 1][offset];
|
||||
|
||||
*p = m_attribute.data[ ( data >> 6 ) ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ data & 0x03 ]; p++;
|
||||
}
|
||||
*p = m_attribute.data[ ( data >> 6 ) ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 4 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ ( data >> 2 ) & 0x03 ]; p++;
|
||||
*p = m_attribute.data[ data & 0x03 ]; p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -815,28 +822,31 @@ CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics )
|
||||
|
||||
uint8_t mask = m_attribute.data[0x12] & 0x0f;
|
||||
|
||||
for ( int i = 0; i < x_count; i++ )
|
||||
uint16_t offset = ma;
|
||||
uint16_t data0 = m_plane[0][offset];
|
||||
uint16_t data1 = m_plane[1][offset] << 1;
|
||||
uint16_t data2 = m_plane[2][offset] << 2;
|
||||
uint16_t data3 = m_plane[3][offset] << 3;
|
||||
|
||||
for ( int j = 7; j >= 0; j-- )
|
||||
{
|
||||
uint16_t offset = ma + i;
|
||||
uint16_t data0 = m_plane[0][offset];
|
||||
uint16_t data1 = m_plane[1][offset] << 1;
|
||||
uint16_t data2 = m_plane[2][offset] << 2;
|
||||
uint16_t data3 = m_plane[3][offset] << 3;
|
||||
uint16_t col = ( data0 & 0x01 ) | ( data1 & 0x02 ) | ( data2 & 0x04 ) | ( data3 & 0x08 );
|
||||
|
||||
for ( int j = 7; j >= 0; j-- )
|
||||
{
|
||||
uint16_t col = ( data0 & 0x01 ) | ( data1 & 0x02 ) | ( data2 & 0x04 ) | ( data3 & 0x08 );
|
||||
|
||||
col &= mask;
|
||||
col &= mask;
|
||||
|
||||
if ( m_misc_output & 0x80 )
|
||||
p[j] = m_attribute.data[col];
|
||||
|
||||
data0 >>= 1;
|
||||
data1 >>= 1;
|
||||
data2 >>= 1;
|
||||
data3 >>= 1;
|
||||
else
|
||||
{
|
||||
p[j] = m_attribute.data[col] | (BIT(m_attribute.data[col], 4) ? 0x38 : 0);
|
||||
if ( p[j] == 6 )
|
||||
p[j] = 0x14;
|
||||
}
|
||||
p += 8;
|
||||
|
||||
data0 >>= 1;
|
||||
data1 >>= 1;
|
||||
data2 >>= 1;
|
||||
data3 >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -844,57 +854,57 @@ CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics )
|
||||
|
||||
CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_text )
|
||||
{
|
||||
uint16_t *p = &bitmap.pix(y);
|
||||
uint16_t *p = &bitmap.pix(y, x * ( ( m_sequencer.data[0x01] & 0x01 ) ? 8 : 9 ) );
|
||||
|
||||
LOG("%s: y = %d, x_count = %d, ma = %d, ra = %d\n", FUNCNAME, y, x_count, ma, ra );
|
||||
LOG("%s: y = %d, x = %d, ma = %d, ra = %d\n", FUNCNAME, y, x, ma, ra );
|
||||
|
||||
for ( int i = 0; i < x_count; i++ )
|
||||
uint16_t offset = ma;
|
||||
uint8_t chr = m_plane[0][ offset ];
|
||||
uint8_t attr = m_plane[1][ offset ];
|
||||
uint8_t data;
|
||||
uint16_t fg = m_attribute.data[ attr & 0x07 ];
|
||||
uint16_t bg = m_attribute.data[ ( attr >> 4 ) & 0x07 ];
|
||||
|
||||
/* If character set A and B are equal attribute bit 3 is used as intensity */
|
||||
if ( m_charA == m_charB )
|
||||
{
|
||||
uint16_t offset = ma + i;
|
||||
uint8_t chr = m_plane[0][ offset ];
|
||||
uint8_t attr = m_plane[1][ offset ];
|
||||
uint8_t data;
|
||||
uint16_t fg = m_attribute.data[ attr & 0x07 ];
|
||||
uint16_t bg = m_attribute.data[ ( attr >> 4 ) & 0x07 ];
|
||||
|
||||
/* If character set A and B are equal attribute bit 3 is used as intensity */
|
||||
if ( m_charA == m_charB )
|
||||
{
|
||||
/* intensity selector */
|
||||
data = m_charB[ chr * 32 + ra ];
|
||||
fg += ( attr & 0x08 ) ? 0x38 : 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* character set selector */
|
||||
data = ( attr & 0x08 ) ? m_charA[ chr * 32 + ra ] : m_charB[ chr * 32 + ra ];
|
||||
}
|
||||
|
||||
if ( i == cursor_x )
|
||||
{
|
||||
if ( m_frame_cnt & 0x08 )
|
||||
{
|
||||
data = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for blinking */
|
||||
if ( ( m_attribute.data[0x10] & 0x08 ) && ( attr & 0x80 ) && ( m_frame_cnt & 0x10 ) )
|
||||
{
|
||||
data = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
*p = ( data & 0x80 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x40 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x20 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x10 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x08 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x04 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x02 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x01 ) ? fg : bg; p++;
|
||||
/* intensity selector */
|
||||
data = m_charB[ chr * 32 + ra ];
|
||||
if ( !( m_attribute.data[0x10] & 0x08 ) )
|
||||
fg = m_attribute.data[ attr & 0x0f ];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* character set selector */
|
||||
data = ( attr & 0x08 ) ? m_charA[ chr * 32 + ra ] : m_charB[ chr * 32 + ra ];
|
||||
}
|
||||
|
||||
if ( x == cursor_x )
|
||||
{
|
||||
if ( m_frame_cnt & 0x08 )
|
||||
{
|
||||
data = 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for blinking */
|
||||
if ( ( m_attribute.data[0x10] & 0x08 ) && ( attr & 0x80 ) && ( m_frame_cnt & 0x10 ) )
|
||||
{
|
||||
data = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
*p = ( data & 0x80 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x40 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x20 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x10 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x08 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x04 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x02 ) ? fg : bg; p++;
|
||||
*p = ( data & 0x01 ) ? fg : bg; p++;
|
||||
if ( !( m_sequencer.data[0x01] & 0x01 ) )
|
||||
*p = ( m_attribute.data[0x10] & 0x04 ) ? *(p - 1) : bg;
|
||||
}
|
||||
|
||||
|
||||
@ -922,10 +932,10 @@ void isa8_ega_device::change_mode()
|
||||
m_video_mode = EGA_MODE_TEXT;
|
||||
|
||||
/* Set character maps */
|
||||
if ( m_sequencer.data[0x04] & 0x02 )
|
||||
if ( m_sequencer.data[0x04] & 0x01 )
|
||||
{
|
||||
m_charA = m_plane[2] + ( ( m_sequencer.data[0x03] & 0x0c ) >> 1 ) * 0x2000;
|
||||
m_charB = m_plane[2] + ( m_sequencer.data[0x03] & 0x03 ) * 0x2000;
|
||||
m_charA = m_plane[2] + ( ( m_sequencer.data[0x03] & 0x0c ) >> 2 ) * 0x4000;
|
||||
m_charB = m_plane[2] + ( m_sequencer.data[0x03] & 0x03 ) * 0x4000;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -954,7 +964,7 @@ uint8_t isa8_ega_device::read(offs_t offset)
|
||||
{
|
||||
uint8_t data = 0xFF;
|
||||
|
||||
if ( !machine().side_effects_disabled() && ! ( m_sequencer.data[4] & 0x04 ) )
|
||||
if ( !machine().side_effects_disabled() && !( m_graphics_controller.data[5] & 0x10 ) )
|
||||
{
|
||||
/* Fill read latches */
|
||||
m_read_latch[0] = m_plane[0][offset & 0xffff];
|
||||
@ -972,15 +982,22 @@ uint8_t isa8_ega_device::read(offs_t offset)
|
||||
else
|
||||
{
|
||||
// Read mode #0
|
||||
if ( m_sequencer.data[4] & 0x04 )
|
||||
if ( !( m_graphics_controller.data[5] & 0x10 ) )
|
||||
{
|
||||
// Normal addressing mode
|
||||
data = m_plane[ m_graphics_controller.data[4] & 0x03 ][offset & 0xffff];
|
||||
if ( m_graphics_controller.data[6] & 2 )
|
||||
{
|
||||
data = m_plane[ m_graphics_controller.data[4] & 0x03 ][offset & 0xfffe];
|
||||
}
|
||||
else
|
||||
{
|
||||
data = m_plane[ m_graphics_controller.data[4] & 0x03 ][offset & 0xffff];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Odd/Even addressing mode
|
||||
data = m_plane[offset & 1][(offset & 0xffff) >> 1];
|
||||
data = m_plane[offset & 1][offset & 0xfffe];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1058,7 +1075,7 @@ void isa8_ega_device::write(offs_t offset, uint8_t data)
|
||||
alu[2] = m_read_latch[2];
|
||||
alu[3] = m_read_latch[3];
|
||||
target_mask = 0xff;
|
||||
return;
|
||||
break;
|
||||
|
||||
case 2: // Write mode 2
|
||||
d[0] = ( data & 0x01 ) ? 0xff : 0x00;
|
||||
@ -1117,8 +1134,7 @@ void isa8_ega_device::write(offs_t offset, uint8_t data)
|
||||
if ( offset & 1 )
|
||||
{
|
||||
// Odd addresses go to planes 1 and 3
|
||||
|
||||
offset >>= 1;
|
||||
offset &= ~1;
|
||||
|
||||
if ( m_sequencer.data[2] & 0x02 )
|
||||
{
|
||||
@ -1137,8 +1153,6 @@ void isa8_ega_device::write(offs_t offset, uint8_t data)
|
||||
{
|
||||
// Even addresses go to planes 0 and 2
|
||||
|
||||
offset >>= 1;
|
||||
|
||||
if ( m_sequencer.data[2] & 0x01 )
|
||||
{
|
||||
// Plane 0
|
||||
|
@ -23,15 +23,15 @@ DEFINE_DEVICE_TYPE(CRTC_EGA, crtc_ega_device, "crtc_ega", "IBM EGA CRT Controlle
|
||||
crtc_ega_device::crtc_ega_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, CRTC_EGA, tag, owner, clock), device_video_interface(mconfig, *this, false)
|
||||
, m_res_out_de_cb(*this), m_res_out_hsync_cb(*this), m_res_out_vsync_cb(*this), m_res_out_vblank_cb(*this)
|
||||
, m_begin_update_cb(*this), m_row_update_cb(*this), m_end_update_cb(*this)
|
||||
, m_res_out_irq_cb(*this), m_begin_update_cb(*this), m_row_update_cb(*this), m_end_update_cb(*this)
|
||||
, m_horiz_char_total(0), m_horiz_disp(0), m_horiz_blank_start(0), m_horiz_blank_end(0)
|
||||
, m_ena_vert_access(0), m_de_skew(0)
|
||||
, m_horiz_retr_start(0), m_horiz_retr_end(0), m_horiz_retr_skew(0)
|
||||
, m_vert_total(0), m_preset_row_scan(0), m_byte_panning(0), m_max_ras_addr(0), m_scan_doubling(0)
|
||||
, m_vert_total(0), m_preset_row_scan(0), m_byte_panning(0), m_max_ras_addr(0)
|
||||
, m_cursor_start_ras(0), m_cursor_disable(0), m_cursor_end_ras(0), m_cursor_skew(0)
|
||||
, m_disp_start_addr(0), m_cursor_addr(0), m_light_pen_addr(0)
|
||||
, m_vert_retr_start(0), m_vert_retr_end(0)
|
||||
, m_protect(0), m_bandwidth(0), m_vert_disp_end(0), m_offset(0), m_underline_loc(0)
|
||||
, m_irq_enable(0), m_vert_disp_end(0), m_offset(0), m_underline_loc(0)
|
||||
, m_vert_blank_start(0), m_vert_blank_end(0)
|
||||
, m_mode_control(0), m_line_compare(0), m_register_address_latch(0)
|
||||
, m_cursor_state(false), m_cursor_blink_count(0)
|
||||
@ -42,7 +42,7 @@ crtc_ega_device::crtc_ega_device(const machine_config &mconfig, const char *tag,
|
||||
, m_hsync_on_timer(nullptr), m_hsync_off_timer(nullptr), m_light_pen_latch_timer(nullptr)
|
||||
, m_horiz_pix_total(0), m_vert_pix_total(0), m_max_visible_x(0), m_max_visible_y(0)
|
||||
, m_hsync_on_pos(0), m_hsync_off_pos(0), m_vsync_on_pos(0), m_vsync_off_pos(0)
|
||||
, m_current_disp_addr(0), m_light_pen_latched(0), m_has_valid_parameters(false)
|
||||
, m_light_pen_latched(0), m_has_valid_parameters(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -98,23 +98,17 @@ void crtc_ega_device::register_w(uint8_t data)
|
||||
m_horiz_retr_skew = ((data & 0x60) >> 5);
|
||||
m_horiz_blank_end = ((data & 0x80) >> 2) | (m_horiz_blank_end & 0x1f);
|
||||
break;
|
||||
case 0x06: m_vert_total = ((data & 0xff) << 0) | (m_vert_total & 0x0300); break;
|
||||
case 0x07: m_vert_total = ((data & 0x01) << 8) | (m_vert_total & 0x02ff);
|
||||
m_vert_disp_end = ((data & 0x02) << 7) | (m_vert_disp_end & 0x02ff);
|
||||
m_vert_retr_start = ((data & 0x04) << 6) | (m_vert_retr_start & 0x02ff);
|
||||
m_vert_blank_start = ((data & 0x08) << 5) | (m_vert_blank_start & 0x02ff);
|
||||
m_line_compare = ((data & 0x10) << 4) | (m_line_compare & 0x02ff);
|
||||
m_vert_total = ((data & 0x20) << 4) | (m_vert_total & 0x01ff);
|
||||
m_vert_disp_end = ((data & 0x40) << 3) | (m_vert_disp_end & 0x1ff);
|
||||
m_vert_retr_start = ((data & 0x80) << 2) | (m_vert_retr_start & 0x01ff);
|
||||
case 0x06: m_vert_total = ((data & 0xff) << 0) | (m_vert_total & 0x0100); break;
|
||||
case 0x07: m_vert_total = ((data & 0x01) << 8) | (m_vert_total & 0x00ff);
|
||||
m_vert_disp_end = ((data & 0x02) << 7) | (m_vert_disp_end & 0x00ff);
|
||||
m_vert_retr_start = ((data & 0x04) << 6) | (m_vert_retr_start & 0x00ff);
|
||||
m_vert_blank_start = ((data & 0x08) << 5) | (m_vert_blank_start & 0x00ff);
|
||||
m_line_compare = ((data & 0x10) << 4) | (m_line_compare & 0x00ff);
|
||||
break;
|
||||
case 0x08: m_preset_row_scan = data & 0x1f;
|
||||
m_byte_panning = ((data & 0x60) >> 5);
|
||||
break;
|
||||
case 0x09: m_max_ras_addr = data & 0x1f;
|
||||
m_vert_blank_start = ((data & 0x20) << 4) | (m_vert_blank_start & 0x01ff);
|
||||
m_line_compare = ((data & 0x40) << 3) | (m_line_compare & 0x01ff);
|
||||
m_scan_doubling = data & 0x80;
|
||||
break;
|
||||
case 0x0a: m_cursor_start_ras = data & 0x1f;
|
||||
m_cursor_disable = data & 0x20;
|
||||
@ -126,18 +120,21 @@ void crtc_ega_device::register_w(uint8_t data)
|
||||
case 0x0d: m_disp_start_addr = ((data & 0xff) << 0) | (m_disp_start_addr & 0xff00); break;
|
||||
case 0x0e: m_cursor_addr = ((data & 0xff) << 8) | (m_cursor_addr & 0x00ff); break;
|
||||
case 0x0f: m_cursor_addr = ((data & 0xff) << 0) | (m_cursor_addr & 0xff00); break;
|
||||
case 0x10: m_vert_retr_start = ((data & 0xff) << 0) | (m_vert_retr_start & 0x0300); break;
|
||||
case 0x10: m_vert_retr_start = ((data & 0xff) << 0) | (m_vert_retr_start & 0x0100); break;
|
||||
case 0x11: m_vert_retr_end = data & 0x0f;
|
||||
m_bandwidth = data & 0x40;
|
||||
m_protect = data & 0x80;
|
||||
m_irq_enable = data & 0x20;
|
||||
if (data & 0x10)
|
||||
{
|
||||
m_res_out_irq_cb(0);
|
||||
}
|
||||
break;
|
||||
case 0x12: m_vert_disp_end = ((data & 0xff) << 0) | (m_vert_disp_end & 0x0300); break;
|
||||
case 0x12: m_vert_disp_end = ((data & 0xff) << 0) | (m_vert_disp_end & 0x0100); break;
|
||||
case 0x13: m_offset = data & 0xff; break;
|
||||
case 0x14: m_underline_loc = data & 0x7f; break;
|
||||
case 0x15: m_vert_blank_start = ((data & 0xff) << 0) | (m_vert_blank_start & 0x0300); break;
|
||||
case 0x15: m_vert_blank_start = ((data & 0xff) << 0) | (m_vert_blank_start & 0x0100); break;
|
||||
case 0x16: m_vert_blank_end = data & 0x7f; break;
|
||||
case 0x17: m_mode_control = data & 0xff; break;
|
||||
case 0x18: m_line_compare = ((data & 0xff) << 0) | (m_line_compare & 0x0300); break;
|
||||
case 0x18: m_line_compare = ((data & 0xff) << 0) | (m_line_compare & 0x0100); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -283,6 +280,8 @@ void crtc_ega_device::set_vblank(int state)
|
||||
|
||||
if (!m_res_out_vblank_cb.isnull())
|
||||
m_res_out_vblank_cb(m_vblank);
|
||||
if (!m_res_out_irq_cb.isnull() && m_irq_enable)
|
||||
m_res_out_irq_cb(m_vblank);
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,6 +531,7 @@ uint32_t crtc_ega_device::screen_update(screen_device &screen, bitmap_ind16 &bit
|
||||
if (m_has_valid_parameters)
|
||||
{
|
||||
uint16_t y;
|
||||
uint16_t disp_addr = m_disp_start_addr + (m_offset << 1) * cliprect.min_y;
|
||||
|
||||
assert(!m_row_update_cb.isnull());
|
||||
|
||||
@ -539,12 +539,6 @@ uint32_t crtc_ega_device::screen_update(screen_device &screen, bitmap_ind16 &bit
|
||||
if (!m_begin_update_cb.isnull())
|
||||
m_begin_update_cb(bitmap, cliprect);
|
||||
|
||||
if (cliprect.min_y == 0)
|
||||
{
|
||||
/* read the start address at the beginning of the frame */
|
||||
m_current_disp_addr = m_disp_start_addr;
|
||||
}
|
||||
|
||||
/* for each row in the visible region */
|
||||
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
|
||||
{
|
||||
@ -555,18 +549,30 @@ uint32_t crtc_ega_device::screen_update(screen_device &screen, bitmap_ind16 &bit
|
||||
int cursor_visible = m_cursor_state &&
|
||||
(ra >= (m_cursor_start_ras & 0x1f)) &&
|
||||
( (ra <= (m_cursor_end_ras & 0x1f)) || ((m_cursor_end_ras & 0x1f) == 0x00 )) &&
|
||||
(m_cursor_addr >= m_current_disp_addr) &&
|
||||
(m_cursor_addr < (m_current_disp_addr + ( m_horiz_disp + 1 )));
|
||||
(m_cursor_addr >= disp_addr) &&
|
||||
(m_cursor_addr < (disp_addr + ( m_horiz_disp + 1 )));
|
||||
|
||||
/* compute the cursor X position, or -1 if not visible */
|
||||
int8_t cursor_x = cursor_visible ? (m_cursor_addr - m_current_disp_addr) : -1;
|
||||
int8_t cursor_x = cursor_visible ? (m_cursor_addr - disp_addr) : -1;
|
||||
|
||||
/* call the external system to draw it */
|
||||
m_row_update_cb(bitmap, cliprect, m_current_disp_addr, ra, y, m_horiz_disp + 1, cursor_x);
|
||||
for (uint8_t x = 0; x < m_horiz_disp + 1; x++)
|
||||
{
|
||||
uint16_t out_addr = BIT(m_mode_control, 6) ? disp_addr + x : (BIT(m_mode_control, 5) ? bitswap<16>(disp_addr + x,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,15) :
|
||||
bitswap<16>(disp_addr + x,15,14,12,11,10,9,8,7,6,5,4,3,2,1,0,13));
|
||||
if (!BIT(m_mode_control, 0))
|
||||
out_addr = (out_addr & ~(1 << 13)) | ((ra & 1) << 13);
|
||||
if (!BIT(m_mode_control, 1))
|
||||
out_addr = (out_addr & ~(2 << 13)) | ((ra & 2) << 13);
|
||||
m_row_update_cb(bitmap, cliprect, out_addr, ra, y, x, cursor_x);
|
||||
}
|
||||
|
||||
/* update MA if the last raster address */
|
||||
if (ra == m_max_ras_addr)
|
||||
m_current_disp_addr = (m_current_disp_addr + m_horiz_disp + 1) & 0xffff;
|
||||
disp_addr += (m_offset << 1);
|
||||
|
||||
if (y == m_line_compare)
|
||||
disp_addr = 0;
|
||||
}
|
||||
|
||||
/* call the tear down function if any */
|
||||
@ -592,6 +598,7 @@ void crtc_ega_device::device_start()
|
||||
m_res_out_hsync_cb.resolve();
|
||||
m_res_out_vsync_cb.resolve();
|
||||
m_res_out_vblank_cb.resolve();
|
||||
m_res_out_irq_cb.resolve();
|
||||
|
||||
/* bind delegates */
|
||||
m_begin_update_cb.resolve();
|
||||
@ -619,7 +626,6 @@ void crtc_ega_device::device_start()
|
||||
m_horiz_retr_skew = 0;
|
||||
m_preset_row_scan = 0;
|
||||
m_byte_panning = 0;
|
||||
m_scan_doubling = 0;
|
||||
m_cursor_start_ras = 0x20;
|
||||
m_cursor_disable = 0;
|
||||
m_cursor_end_ras = 0;
|
||||
@ -627,8 +633,6 @@ void crtc_ega_device::device_start()
|
||||
m_disp_start_addr = 0;
|
||||
m_light_pen_addr = 0;
|
||||
m_vert_retr_end = 0;
|
||||
m_protect = 0;
|
||||
m_bandwidth = 0;
|
||||
m_offset = 0;
|
||||
m_underline_loc = 0;
|
||||
m_vert_blank_end = 0;
|
||||
@ -649,7 +653,6 @@ void crtc_ega_device::device_start()
|
||||
m_vsync_ff = 0;
|
||||
m_adjust_active = 0;
|
||||
|
||||
m_current_disp_addr = 0;
|
||||
m_light_pen_latched = false;
|
||||
m_has_valid_parameters = false;
|
||||
|
||||
@ -678,13 +681,10 @@ void crtc_ega_device::device_start()
|
||||
save_item(NAME(m_preset_row_scan));
|
||||
save_item(NAME(m_byte_panning));
|
||||
save_item(NAME(m_max_ras_addr));
|
||||
save_item(NAME(m_scan_doubling));
|
||||
save_item(NAME(m_cursor_disable));
|
||||
save_item(NAME(m_cursor_skew));
|
||||
save_item(NAME(m_vert_retr_start));
|
||||
save_item(NAME(m_vert_retr_end));
|
||||
save_item(NAME(m_protect));
|
||||
save_item(NAME(m_bandwidth));
|
||||
save_item(NAME(m_vert_disp_end));
|
||||
save_item(NAME(m_offset));
|
||||
save_item(NAME(m_underline_loc));
|
||||
@ -709,6 +709,9 @@ void crtc_ega_device::device_reset()
|
||||
if (!m_res_out_vblank_cb.isnull())
|
||||
m_res_out_vblank_cb(false);
|
||||
|
||||
if(!m_res_out_irq_cb.isnull())
|
||||
m_res_out_irq_cb(false);
|
||||
|
||||
if (!m_line_timer->enabled())
|
||||
{
|
||||
m_line_timer->adjust( attotime::from_ticks( m_horiz_char_total + 2, m_clock ) );
|
||||
|
@ -13,7 +13,7 @@
|
||||
#define CRTC_EGA_BEGIN_UPDATE(_name) void _name(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
#define CRTC_EGA_ROW_UPDATE(_name) void _name(bitmap_ind16 &bitmap, \
|
||||
const rectangle &cliprect, uint16_t ma, uint8_t ra, \
|
||||
uint16_t y, uint8_t x_count, int8_t cursor_x)
|
||||
uint16_t y, uint8_t x, int8_t cursor_x)
|
||||
#define CRTC_EGA_END_UPDATE(_name) void _name(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ public:
|
||||
auto res_out_hsync_callback() { return m_res_out_hsync_cb.bind(); }
|
||||
auto res_out_vsync_callback() { return m_res_out_vsync_cb.bind(); }
|
||||
auto res_out_vblank_callback() { return m_res_out_vblank_cb.bind(); }
|
||||
auto res_out_irq_callback() { return m_res_out_irq_cb.bind(); }
|
||||
|
||||
template <typename... T> void set_begin_update_callback(T &&... args) { m_begin_update_cb.set(std::forward<T>(args)...); }
|
||||
template <typename... T> void set_row_update_callback(T &&... args) { m_row_update_cb.set(std::forward<T>(args)...); }
|
||||
@ -79,6 +80,7 @@ private:
|
||||
devcb_write_line m_res_out_hsync_cb;
|
||||
devcb_write_line m_res_out_vsync_cb;
|
||||
devcb_write_line m_res_out_vblank_cb;
|
||||
devcb_write_line m_res_out_irq_cb;
|
||||
|
||||
/* if specified, this gets called before any pixel update,
|
||||
optionally return a pointer that will be passed to the
|
||||
@ -108,7 +110,6 @@ private:
|
||||
uint8_t m_preset_row_scan; /* 0x08 */
|
||||
uint8_t m_byte_panning; /* 0x08 */
|
||||
uint8_t m_max_ras_addr; /* 0x09 */
|
||||
uint8_t m_scan_doubling; /* 0x09 */
|
||||
uint8_t m_cursor_start_ras; /* 0x0a */
|
||||
uint8_t m_cursor_disable; /* 0x0a */
|
||||
uint8_t m_cursor_end_ras; /* 0x0b */
|
||||
@ -118,8 +119,7 @@ private:
|
||||
uint16_t m_light_pen_addr; /* 0x10/0x11 */
|
||||
uint16_t m_vert_retr_start; /* 0x10/0x07 */
|
||||
uint8_t m_vert_retr_end; /* 0x11 */
|
||||
uint8_t m_protect; /* 0x11 */
|
||||
uint8_t m_bandwidth; /* 0x11 */
|
||||
uint8_t m_irq_enable; /* 0x11 */
|
||||
uint16_t m_vert_disp_end; /* 0x12/0x07 */
|
||||
uint8_t m_offset; /* 0x13 */
|
||||
uint8_t m_underline_loc; /* 0x14 */
|
||||
@ -171,7 +171,6 @@ private:
|
||||
uint16_t m_hsync_off_pos;
|
||||
uint16_t m_vsync_on_pos;
|
||||
uint16_t m_vsync_off_pos;
|
||||
uint16_t m_current_disp_addr; /* the display address currently drawn */
|
||||
uint8_t m_light_pen_latched;
|
||||
bool m_has_valid_parameters;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user