diff options
Diffstat (limited to 'src/devices/bus/isa/ega.cpp')
-rw-r--r-- | src/devices/bus/isa/ega.cpp | 265 |
1 files changed, 142 insertions, 123 deletions
diff --git a/src/devices/bus/isa/ega.cpp b/src/devices/bus/isa/ega.cpp index 71665cd62dd..da9ea8550de 100644 --- a/src/devices/bus/isa/ega.cpp +++ b/src/devices/bus/isa/ega.cpp @@ -446,8 +446,6 @@ located at I/O port 0x3CE, and a data register located at I/O port 0x3CF. #include "emu.h" #include "ega.h" -#include "screen.h" - #define LOG_READ (1U << 1) #define LOG_SETUP (1U << 2) #define LOG_MODE (1U << 3) @@ -507,23 +505,23 @@ ROM_END INPUT_PORTS_START( ega ) PORT_START( "config" ) - PORT_CONFNAME( 0x0f, 0x09, "dipswitches" ) - PORT_CONFSETTING( 0x00, "0000 - MDA PRIMARY, EGA COLOR, 40x25" ) /* DIAG: ?? 40 cols, RGBI */ - PORT_CONFSETTING( 0x08, "0001 - MDA PRIMARY, EGA COLOR, 80x25" ) /* DIAG: ?? 80 cols, RGBI */ - PORT_CONFSETTING( 0x04, "0010 - MDA PRIMARY, EGA HI RES EMULATE (SAME AS 0001)" ) /* DIAG: ?? 80 cols, RGBI */ - PORT_CONFSETTING( 0x0c, "0011 - MDA PRIMARY, EGA HI RES ENHANCED" ) /* DIAG: Color Display 40 cols, RrGgBb */ - PORT_CONFSETTING( 0x02, "0100 - CGA 40 PRIMARY, EGA MONOCHROME" ) /* DIAG: ??, Mono RGBI */ - PORT_CONFSETTING( 0x0a, "0101 - CGA 80 PRIMARY, EGA MONOCHROME" ) /* DIAG: ??, Mono RGBI */ - PORT_CONFSETTING( 0x06, "0110 - MDA SECONDARY, EGA COLOR, 40x25" ) /* DIAG: Color Display 40 cols, RGBI */ - PORT_CONFSETTING( 0x0e, "0111 - MDA SECONDARY, EGA COLOR, 80x25" ) /* DIAG: Color Display 80 cols, RGBI */ - PORT_CONFSETTING( 0x01, "1000 - MDA SECONDARY, EGA HI RES EMULATE (SAME AS 0111)" ) /* DIAG: Color Display 80 cols, RGBI */ - PORT_CONFSETTING( 0x09, "1001 - MDA SECONDARY, EGA HI RES ENHANCED" ) /* DIAG: Color Display 40 cols, RrGgBb */ - PORT_CONFSETTING( 0x05, "1010 - COLOR 40 SECONDARY, EGA" ) /* DIAG: Monochrome display, Mono RGBI */ - PORT_CONFSETTING( 0x0d, "1011 - COLOR 80 SECONDARY, EGA" ) /* DIAG: Monochrome display, Mono RGBI */ - PORT_CONFSETTING( 0x03, "1100 - RESERVED" ) /* ??, RGBI */ - PORT_CONFSETTING( 0x0b, "1101 - RESERVED" ) /* ??, RGBI */ - PORT_CONFSETTING( 0x07, "1110 - RESERVED" ) /* ??, RGBI */ - PORT_CONFSETTING( 0x0f, "1111 - RESERVED" ) /* ??, RGBI */ + PORT_DIPNAME( 0x0f, 0x09, "Display Type" ) + PORT_DIPSETTING( 0x00, "0000 - MDA PRIMARY, EGA COLOR, 40x25" ) /* DIAG: ?? 40 cols, RGBI */ + PORT_DIPSETTING( 0x08, "0001 - MDA PRIMARY, EGA COLOR, 80x25" ) /* DIAG: ?? 80 cols, RGBI */ + PORT_DIPSETTING( 0x04, "0010 - MDA PRIMARY, EGA HI RES EMULATE (SAME AS 0001)" ) /* DIAG: ?? 80 cols, RGBI */ + PORT_DIPSETTING( 0x0c, "0011 - MDA PRIMARY, EGA HI RES ENHANCED" ) /* DIAG: Color Display 40 cols, RrGgBb */ + PORT_DIPSETTING( 0x02, "0100 - CGA 40 PRIMARY, EGA MONOCHROME" ) /* DIAG: ??, Mono RGBI */ + PORT_DIPSETTING( 0x0a, "0101 - CGA 80 PRIMARY, EGA MONOCHROME" ) /* DIAG: ??, Mono RGBI */ + PORT_DIPSETTING( 0x06, "0110 - MDA SECONDARY, EGA COLOR, 40x25" ) /* DIAG: Color Display 40 cols, RGBI */ + PORT_DIPSETTING( 0x0e, "0111 - MDA SECONDARY, EGA COLOR, 80x25" ) /* DIAG: Color Display 80 cols, RGBI */ + PORT_DIPSETTING( 0x01, "1000 - MDA SECONDARY, EGA HI RES EMULATE (SAME AS 0111)" ) /* DIAG: Color Display 80 cols, RGBI */ + PORT_DIPSETTING( 0x09, "1001 - MDA SECONDARY, EGA HI RES ENHANCED" ) /* DIAG: Color Display 40 cols, RrGgBb */ + PORT_DIPSETTING( 0x05, "1010 - COLOR 40 SECONDARY, EGA" ) /* DIAG: Monochrome display, Mono RGBI */ + PORT_DIPSETTING( 0x0d, "1011 - COLOR 80 SECONDARY, EGA" ) /* DIAG: Monochrome display, Mono RGBI */ + PORT_DIPSETTING( 0x03, "1100 - RESERVED" ) /* ??, RGBI */ + PORT_DIPSETTING( 0x0b, "1101 - RESERVED" ) /* ??, RGBI */ + PORT_DIPSETTING( 0x07, "1110 - RESERVED" ) /* ??, RGBI */ + PORT_DIPSETTING( 0x0f, "1111 - RESERVED" ) /* ??, RGBI */ INPUT_PORTS_END //************************************************************************** @@ -539,10 +537,10 @@ DEFINE_DEVICE_TYPE(ISA8_EGA, isa8_ega_device, "ega", "IBM Enhanced Graphics Adap void isa8_ega_device::device_add_mconfig(machine_config &config) { - screen_device &screen(SCREEN(config, EGA_SCREEN_NAME, SCREEN_TYPE_RASTER)); - screen.set_raw(16.257_MHz_XTAL, 912, 0, 640, 262, 0, 200); - screen.set_screen_update(EGA_CRTC_NAME, FUNC(crtc_ega_device::screen_update)); - screen.set_palette(m_palette); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(16.257_MHz_XTAL, 912, 0, 640, 262, 0, 200); + m_screen->set_screen_update(EGA_CRTC_NAME, FUNC(crtc_ega_device::screen_update)); + m_screen->set_palette(m_palette); PALETTE(config, m_palette).set_entries(64); @@ -554,6 +552,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_irq = state; m_isa->irq2_w(state); }); } //------------------------------------------------- @@ -587,8 +586,8 @@ isa8_ega_device::isa8_ega_device(const machine_config &mconfig, device_type type device_t(mconfig, type, tag, owner, clock), device_isa8_card_interface(mconfig, *this), m_crtc_ega(*this, EGA_CRTC_NAME), m_videoram(nullptr), m_charA(nullptr), m_charB(nullptr), - m_misc_output(0), m_feature_control(0), m_frame_cnt(0), m_hsync(0), m_vsync(0), m_vblank(0), m_display_enable(0), m_video_mode(0), - m_palette(*this, "palette") + m_misc_output(0), m_feature_control(0), m_frame_cnt(0), m_hsync(0), m_vsync(0), m_vblank(0), m_display_enable(0), m_irq(0), m_video_mode(0), + m_palette(*this, "palette"), m_screen(*this, EGA_SCREEN_NAME) { } @@ -636,6 +635,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))); @@ -659,6 +667,7 @@ void isa8_ega_device::device_reset() m_vsync = 0; m_vblank = 0; m_display_enable = 0; + m_irq = 0; install_banks(); @@ -744,28 +753,28 @@ void isa8_ega_device::install_banks() } } -CRTC_EGA_ROW_UPDATE( isa8_ega_device::ega_update_row ) +CRTC_EGA_PIXEL_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); } -WRITE_LINE_MEMBER( isa8_ega_device::de_changed ) +void isa8_ega_device::de_changed(int state) { m_display_enable = state ? 1 : 0; } -WRITE_LINE_MEMBER( isa8_ega_device::hsync_changed ) +void isa8_ega_device::hsync_changed(int state) { m_hsync = state ? 1 : 0; } -WRITE_LINE_MEMBER( isa8_ega_device::vsync_changed ) +void isa8_ega_device::vsync_changed(int state) { m_vsync = state ? 1 : 0; if ( state ) @@ -775,39 +784,36 @@ WRITE_LINE_MEMBER( isa8_ega_device::vsync_changed ) } -WRITE_LINE_MEMBER( isa8_ega_device::vblank_changed ) +void isa8_ega_device::vblank_changed(int state) { m_vblank = state ? 8 : 0; } -CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_graphics ) +CRTC_EGA_PIXEL_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,86 +821,95 @@ 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; } } } -CRTC_EGA_ROW_UPDATE( isa8_ega_device::pc_ega_text ) +CRTC_EGA_PIXEL_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; + uint8_t blink = m_attribute.data[0x10] & 0x08; + uint16_t fg = m_attribute.data[ attr & 0x0f ]; + uint16_t bg = m_attribute.data[ ( attr >> 4 ) & (blink ? 0x07 : 0x0f) ]; + + if ( m_charA == m_charB ) + data = m_charB[ chr * 32 + ra ]; + else { - 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 ]; - } + /* character set selector */ + data = ( attr & 0x08 ) ? m_charA[ chr * 32 + ra ] : m_charB[ chr * 32 + ra ]; + fg &= 0x07; + } + + if(m_screen->visible_area().height() == 200) // the ibm 5154 forces cga compatibility in 200 line modes + { + fg = fg | (BIT(fg, 4) ? 0x38 : 0); + if ( fg == 6 ) + fg = 0x14; + bg = bg | (BIT(bg, 4) ? 0x38 : 0); + if ( bg == 6 ) + bg = 0x14; + } - 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 +937,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 +969,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 +987,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 +1080,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 +1139,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 +1158,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 @@ -1275,7 +1294,7 @@ uint8_t isa8_ega_device::pc_ega8_3c0_r(offs_t offset) data = ( data & 0x0f ); data |= ( ( m_feature_control & 0x03 ) << 5 ); - data |= ( m_vsync ? 0x00 : 0x80 ); + data |= ( m_irq ? 0x00 : 0x80 ); data |= ( ( ( dips >> ( ( ( m_misc_output & 0x0c ) >> 2 ) ) ) & 0x01 ) << 4 ); } break; @@ -1345,7 +1364,7 @@ void isa8_ega_device::pc_ega8_3c0_w(offs_t offset, uint8_t data) m_attribute.index_write ^= 0x01; break; - /* Misccellaneous Output */ + /* Miscellaneous Output */ case 2: m_misc_output = data; install_banks(); |