From c690b478d9677ee1931e111ebc1eafca6da5ee7f Mon Sep 17 00:00:00 2001 From: Scott Stone Date: Mon, 2 Sep 2013 03:37:18 +0000 Subject: [PATCH] (MESS) vtvideo.c : 132 column mode uses compressed characters with 1 filler pixel instead of 2. Bold implemented: 3 color palette and separate device_reset() on Rainbow. Double width line attribute fix. [Bavarese] (MESS) vtvideo.h : separate device_reset(). New variable m_height_MAX for those parts of the code shared with VT-100. [Bavarese] (NESS) rainbow.c : changed GAME_NO_SOUND to GAME_IMPERFECT_COLORS. [Bavarese] --- src/mess/drivers/rainbow.c | 6 +- src/mess/video/vtvideo.c | 190 ++++++++++++++++++++++++------------- src/mess/video/vtvideo.h | 3 +- 3 files changed, 131 insertions(+), 68 deletions(-) diff --git a/src/mess/drivers/rainbow.c b/src/mess/drivers/rainbow.c index 1a90aaef2ce..300ca135c32 100644 --- a/src/mess/drivers/rainbow.c +++ b/src/mess/drivers/rainbow.c @@ -600,7 +600,7 @@ READ8_MEMBER( rainbow_state::diagnostic_r ) // printf("%02x DIP value ORed to diagnostic\n", ( m_inp1->read() | m_inp2->read() | m_inp3->read() ) ); return ( (m_diagnostic & (0xf1)) | ( m_inp1->read() | - m_inp2->read() | + m_inp2->read() | m_inp3->read() ) ); } @@ -758,7 +758,7 @@ static MACHINE_CONFIG_START( rainbow, rainbow_state ) MCFG_SCREEN_VISIBLE_AREA(0, 80*10-1, 0, 25*10-1) MCFG_SCREEN_UPDATE_DRIVER(rainbow_state, screen_update_rainbow) MCFG_GFXDECODE(rainbow) - MCFG_PALETTE_LENGTH(2) + MCFG_PALETTE_LENGTH(3) MCFG_PALETTE_INIT_OVERRIDE(driver_device, monochrome_green) MCFG_RAINBOW_VIDEO_ADD("vt100_video", video_interface) @@ -796,4 +796,4 @@ ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */ -COMP( 1982, rainbow, 0, 0, rainbow, rainbow, driver_device, 0, "Digital Equipment Corporation", "Rainbow 100B", GAME_NOT_WORKING | GAME_NO_SOUND) +COMP( 1982, rainbow, 0, 0, rainbow, rainbow, driver_device, 0, "Digital Equipment Corporation", "Rainbow 100B", GAME_NOT_WORKING | GAME_IMPERFECT_COLORS) diff --git a/src/mess/video/vtvideo.c b/src/mess/video/vtvideo.c index 424dc9912ef..bcfa4d3304f 100644 --- a/src/mess/video/vtvideo.c +++ b/src/mess/video/vtvideo.c @@ -92,6 +92,7 @@ void vt100_video_device::device_start() save_item(NAME(m_basic_attribute)); save_item(NAME(m_columns)); save_item(NAME(m_height)); + save_item(NAME(m_height_MAX)); save_item(NAME(m_skip_lines)); save_item(NAME(m_frequency)); save_item(NAME(m_interlaced)); @@ -105,8 +106,10 @@ void vt100_video_device::device_reset() { palette_set_color_rgb(machine(), 0, 0x00, 0x00, 0x00); // black palette_set_color_rgb(machine(), 1, 0xff, 0xff, 0xff); // white - + m_height = 25; + m_height_MAX = 25; + m_lba7 = 0; m_scroll_latch = 0; @@ -120,20 +123,49 @@ void vt100_video_device::device_reset() m_skip_lines = 2; // for 60Hz } +// ****** RAINBOW ****** +// 3 color palette, 24 and 48 line modes. +void rainbow_video_device::device_reset() +{ + palette_set_color_rgb(machine(), 0, 0x00, 0x00, 0x00); // black + palette_set_color_rgb(machine(), 1, 213, 146, 82); // ORANGE (not exact) + palette_set_color_rgb(machine(), 2, 255, 193, 129); // ORANGE (brighter) + + m_height = 24; // <---- DEC-100 + m_height_MAX = 48; + + m_lba7 = 0; + + m_scroll_latch = 0; + m_blink_flip_flop = 0; + m_reverse_field = 0; + m_basic_attribute = 0; + + m_columns = 80; + m_frequency = 60; + m_interlaced = 1; + m_skip_lines = 2; // for 60Hz +} /*************************************************************************** IMPLEMENTATION ***************************************************************************/ +// Also used by Rainbow-100 ************ void vt100_video_device::recompute_parameters() { int horiz_pix_total = 0; int vert_pix_total = 0; rectangle visarea; - horiz_pix_total = m_columns * 10; - vert_pix_total = m_height * 10; + vert_pix_total = m_height * 10; + if (m_columns == 132) { + horiz_pix_total = m_columns * 9; // display 1 less filler pixel in 132 char. mode (DEC-100) + } else { + horiz_pix_total = m_columns * 10; // normal 80 character mode. + } + visarea.set(0, horiz_pix_total - 1, 0, vert_pix_total - 1); m_screen->configure(horiz_pix_total, vert_pix_total, visarea, m_screen->frame_period().attoseconds); @@ -145,7 +177,7 @@ READ8_MEMBER( vt100_video_device::lba7_r ) return m_lba7; } - +// Also used by Rainbow-100 ************ WRITE8_MEMBER( vt100_video_device::dc012_w ) { if (!(data & 0x08)) @@ -187,31 +219,34 @@ WRITE8_MEMBER( vt100_video_device::dc012_w ) m_blink_flip_flop = 0; break; case 0x0d: - // set basic attribute to reverse video + // set basic attribute to reverse video / blink flip-flop off m_basic_attribute = 1; m_blink_flip_flop = 0; - if (m_height != 25) - { - m_height = 25; // -1 = 24 lines (default) - recompute_parameters(); - } - break; - case 0x0e: - // (DC12) : not supported - break; - case 0x0f: - // (VT100) : reserved for future specification + if (m_height_MAX == 25) break; // VT 100. + + if (m_height != 24) + { + m_height = 24; // (DEC Rainbow 100) : 24 line display + recompute_parameters(); + } + break; + + case 0x0e: + break; // (DC12) : 'not supported' + + case 0x0f: // (DEC Rainbow 100) : set basic attribute to reverse video / blink flip-flop off m_basic_attribute = 1; m_blink_flip_flop = 0; - - // (DEC Rainbow 100) : 48 line display - if (m_height != 49) + + if (m_height_MAX == 25) break; // VT 100. + + if (m_height != 48) { - m_height = 49; + m_height = 48; // (DEC Rainbow 100) : 48 line display recompute_parameters(); - } + } break; } } @@ -258,6 +293,8 @@ WRITE8_MEMBER( vt100_video_device::brightness_w ) //palette_set_color_rgb(machine(), 1, data, data, data); } + + void vt100_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type) { UINT8 line = 0; @@ -381,21 +418,30 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli } +// ****** RAINBOW ****** // 5 possible character states (normal, reverse, bold, blink, underline) are encoded into display_type. -// TODO: bold not implemented yet - void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type) { + UINT8 xsize, d_xsize; + if (m_columns == 132) + { xsize = 9; + d_xsize = 18; + } else + { + xsize = 10; + d_xsize = 20; + } + UINT8 line = 0; - int bit = 0, j, invert, blink, underline; - - invert = display_type & 4; // BIT 2 indicates REVERSE -// bold = display_type & 8; // BIT 3 indicates BOLD - blink = display_type & 16; // BIT 4 indicates BLINK - underline = display_type & 32; // BIT 5 indicates UNDERLINE + int bit = 0, j=0, invert, bold, blink, underline; + invert = display_type & 8; // BIT 3 indicates REVERSE + bold = (display_type & 16) >> 4; // BIT 4 indicates BOLD + blink = display_type & 32; // BIT 5 indicates BLINK + underline = display_type & 64; // BIT 6 indicates UNDERLINE display_type = display_type & 3; - int double_width = (display_type == 2) ? 1 : 0; + int double_width = (display_type == 1) ? 1 : 0; for (int i = 0; i < 10; i++) { @@ -403,31 +449,30 @@ void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, { case 0 : // bottom half, double height j = (i >> 1) + 5; break; - case 1 : // top half, double height + case 2 : // top half, double height j = (i >> 1); break; - case 2 : // double width - case 3 : // normal - j = i; break; - default : j = 0; break; + + default : j = i; break; // 1: double width / 3: normal } // modify line since that is how it is stored in rom if (j == 0) j = 15; else j = j - 1; line = m_gfx[code * 16 + j]; + if ( i == 8 ) { if ( underline != 0 ) line = 0xff; } - - // TODO: test if basic attribute behaves the same on DEC-100 + + // TODO: verify if basic attribute behaves the same on DEC-100 if ( m_basic_attribute == 1 ) { { - line = line ^ 0xff; + line = line ^ 0xff; } } - if (m_blink_flip_flop > 0) + if (m_blink_flip_flop > 0) { if ( blink != 0 ) { @@ -439,33 +484,39 @@ void rainbow_video_device::display_char(bitmap_ind16 &bitmap, UINT8 code, int x, for (int b = 0; b < 8; b++) { - bit = BIT((line << b), 7); + bit = BIT((line << b), 7) << bold; if (double_width) { - bitmap.pix16(y * 10 + i, x * 20 + b * 2) = bit; - bitmap.pix16(y * 10 + i, x * 20 + b * 2 + 1) = bit; + bitmap.pix16(y * 10 + i, x * d_xsize + b * 2) = bit; + bitmap.pix16(y * 10 + i, x * d_xsize + b * 2 + 1) = bit; } else { - bitmap.pix16(y * 10 + i, x * 10 + b) = bit; + bitmap.pix16(y * 10 + i, x * xsize + b) = bit; } } + + // char interleave is filled with last bit if (double_width) { - bitmap.pix16(y * 10 + i, x * 20 + 16) = bit; - bitmap.pix16(y * 10 + i, x * 20 + 17) = bit; - bitmap.pix16(y * 10 + i, x * 20 + 18) = bit; - bitmap.pix16(y * 10 + i, x * 20 + 19) = bit; + bitmap.pix16(y * 10 + i, x * d_xsize + 16) = bit; + bitmap.pix16(y * 10 + i, x * d_xsize + 17) = bit; + bitmap.pix16(y * 10 + i, x * d_xsize + 18) = bit; + bitmap.pix16(y * 10 + i, x * d_xsize + 19) = bit; } else { - bitmap.pix16(y * 10 + i, x * 10 + 8) = bit; - bitmap.pix16(y * 10 + i, x * 10 + 9) = bit; + bitmap.pix16(y * 10 + i, x * xsize + 8) = bit; + if (m_columns == 80) + bitmap.pix16(y * 10 + i, x * xsize + 9) = bit; } + + } } +// ****** RAINBOW ****** void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cliprect) { UINT16 addr = 0; @@ -487,20 +538,31 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c // end of line, fill empty till end of line if (line >= m_skip_lines) { - for (x = xpos; x < ((display_type == 2) ? (m_columns / 2) : m_columns); x++) + // NOTE: display_type is already SHIFTED by 1 ( 1 = DOUBLE WIDTH 40 / 66 ) + for (x = xpos; x < ((display_type == 1) ? (m_columns / 2) : m_columns); x++) { display_char(bitmap, code, x, ypos, scroll_region, display_type); } } // move to new data temp = m_in_ram_func(addr + xpos + 2) * 256 + m_in_ram_func(addr + xpos + 1); + addr = (temp) & 0x0fff; attr_addr = ((temp) & 0x1fff) - 2; - // if A12 is 1 then it is 0x2000 block, if 0 then 0x4000 (AVO) - if (temp & 0x1000) attr_addr &= 0xfff; else attr_addr |= 0x1000; - temp = m_in_ram_func(attr_addr); - scroll_region = (temp) & 1; - display_type = (temp>> 1) & 3; + + // No AVO here. + attr_addr |= 0x1000; + if (attr_addr > 0x2000) // Ignore attributes beyond 8192 byte limit (SRAM). + { + scroll_region = 1; // binary 1 <- SET DEFAULTS + display_type = 3; // binary 111 + } else + { + temp = m_in_ram_func(attr_addr); + scroll_region = (temp) & 1; + display_type = (temp >> 1) & 3; + } + if (line >= m_skip_lines) { ypos++; @@ -510,22 +572,22 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c } else { - // display regular char + // display regular char if (line >= m_skip_lines) { attr_addr = 0x1000 | ( (addr + xpos) & 0x0fff ); temp = m_in_ram_func(attr_addr); // get character attribute // TODO: check if reverse bit is treated the same way on real hardware - // 1 = display char. in REVERSE (encoded as 4) - // 0 = display char. in BOLD (encoded as 8) - // 0 = display char. w. BLINK (encoded as 16) - // 0 = display char. w. UNDERLINE (encoded as 32). - display_char(bitmap, code, xpos, ypos, scroll_region, display_type | ( ( (temp & 1)) << 2 ) - | ( (2-(temp & 2)) << 2 ) - | ( (4-(temp & 4)) << 2 ) - | ( (8-(temp & 8)) << 2 ) - ); + // 1 = display char. in REVERSE (encoded as 8) + // 0 = display char. in BOLD (encoded as 16) + // 0 = display char. w. BLINK (encoded as 32) + // 0 = display char. w. UNDERLINE (encoded as 64). + display_char(bitmap, code, xpos, ypos, scroll_region, display_type | ( ( (temp & 1)) << 3 ) + | ( (2-(temp & 2)) << 3 ) + | ( (4-(temp & 4)) << 3 ) + | ( (8-(temp & 8)) << 3 ) + ); } xpos++; if (xpos > m_columns) diff --git a/src/mess/video/vtvideo.h b/src/mess/video/vtvideo.h index df6ac5cf8d2..56514282c7e 100644 --- a/src/mess/video/vtvideo.h +++ b/src/mess/video/vtvideo.h @@ -67,6 +67,7 @@ protected: // dc011 attributes UINT8 m_columns; UINT8 m_height; + UINT8 m_height_MAX; UINT8 m_skip_lines; UINT8 m_frequency; UINT8 m_interlaced; @@ -82,7 +83,7 @@ public: protected: virtual void display_char(bitmap_ind16 &bitmap, UINT8 code, int x, int y, UINT8 scroll_region, UINT8 display_type); - + virtual void device_reset(); }; extern const device_type VT100_VIDEO;