diff options
author | 2022-06-04 23:51:00 -0500 | |
---|---|---|
committer | 2022-06-04 23:51:00 -0500 | |
commit | ad7cbf9c0a1d888d28d70b2c29c20350592482e0 (patch) | |
tree | aa5ea669d4593187684ffac752b19143c0030681 /src/devices/bus/isa | |
parent | ce212a5e9a7a37df60b93c7805c3828beb40620a (diff) |
ega: palette and memory map fixes
Diffstat (limited to 'src/devices/bus/isa')
-rw-r--r-- | src/devices/bus/isa/ega.cpp | 192 |
1 files changed, 103 insertions, 89 deletions
diff --git a/src/devices/bus/isa/ega.cpp b/src/devices/bus/isa/ega.cpp index a1e9eafbdf7..2c5f78311f5 100644 --- a/src/devices/bus/isa/ega.cpp +++ b/src/devices/bus/isa/ega.cpp @@ -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 + 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 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 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 = %d, ma = %d, ra = %d\n", FUNCNAME, y, x, ma, ra ); - LOG("%s: y = %d, x_count = %d, ma = %d, ra = %d\n", FUNCNAME, y, x_count, ma, ra ); + 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 ]; - for ( int i = 0; i < x_count; i++ ) + /* 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 ]; - } + /* 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 ( i == cursor_x ) + if ( x == cursor_x ) + { + if ( m_frame_cnt & 0x08 ) { - if ( m_frame_cnt & 0x08 ) - { - data = 0xFF; - } + data = 0xFF; } - else + } + else + { + /* Check for blinking */ + if ( ( m_attribute.data[0x10] & 0x08 ) && ( attr & 0x80 ) && ( m_frame_cnt & 0x10 ) ) { - /* Check for blinking */ - if ( ( m_attribute.data[0x10] & 0x08 ) && ( attr & 0x80 ) && ( m_frame_cnt & 0x10 ) ) - { - data = 0x00; - } + 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++; } + + *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 |