vtvideo: Accurate reconfiguration parameters; interlace mode for VT100 (nw)

This commit is contained in:
AJR 2017-12-30 23:32:23 -05:00
parent f10b30648e
commit 47ca5bf03a
2 changed files with 57 additions and 60 deletions

View File

@ -66,8 +66,7 @@ PARAMETERS
***************************************************************************/ ***************************************************************************/
#define VERBOSE 1 #define VERBOSE 1
#include "logmacro.h"
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
DEFINE_DEVICE_TYPE(VT100_VIDEO, vt100_video_device, "vt100_video", "VT100 Video") DEFINE_DEVICE_TYPE(VT100_VIDEO, vt100_video_device, "vt100_video", "VT100 Video")
@ -120,7 +119,7 @@ void vt100_video_device::device_start()
save_item(NAME(m_height)); save_item(NAME(m_height));
save_item(NAME(m_height_MAX)); save_item(NAME(m_height_MAX));
save_item(NAME(m_fill_lines)); save_item(NAME(m_fill_lines));
save_item(NAME(m_frequency)); save_item(NAME(m_is_50hz));
save_item(NAME(m_interlaced)); save_item(NAME(m_interlaced));
} }
@ -147,9 +146,9 @@ void vt100_video_device::device_reset()
m_basic_attribute = 0; m_basic_attribute = 0;
m_columns = 80; m_columns = 80;
m_frequency = 60; m_is_50hz = false;
m_interlaced = 1; m_interlaced = true;
m_fill_lines = 2; // for 60Hz m_fill_lines = 2; // for 60Hz
recompute_parameters(); recompute_parameters();
} }
@ -179,9 +178,9 @@ void rainbow_video_device::device_reset()
m_columns = 80; m_columns = 80;
m_frequency = 60; m_is_50hz = false;
m_interlaced = 1; m_interlaced = true;
m_fill_lines = 2; // for 60Hz (not in use any longer -> detected) m_fill_lines = 2; // for 60Hz (not in use any longer -> detected)
recompute_parameters(); recompute_parameters();
} }
@ -193,33 +192,30 @@ IMPLEMENTATION
// Also used by Rainbow-100 ************ // Also used by Rainbow-100 ************
void vt100_video_device::recompute_parameters() void vt100_video_device::recompute_parameters()
{ {
rectangle visarea;
int horiz_pix_total = 0;
// RAINBOW: 240 scan lines in non-interlaced mode (480 interlaced). VT-100 : same (?) // RAINBOW: 240 scan lines in non-interlaced mode (480 interlaced). VT-100 : same (?)
m_linedoubler = false; // 24 "true" lines (240) -OR- 48 lines with NO ghost lines (true 480) m_linedoubler = false; // 24 "true" lines (240) -OR- 48 lines with NO ghost lines (true 480)
if ((m_interlaced) && (m_height == 24)) if ((m_interlaced) && (m_height == 24 || m_height == 25))
m_linedoubler = true; // 24 lines with 'double scan' (false 480) m_linedoubler = true; // 24 lines with 'double scan' (false 480)
int vert_pix_total = ((m_linedoubler == false) ? m_height : m_height_MAX) * 10; int vert_pix_visible = m_height * (m_linedoubler ? 20 : 10);
int vert_pix_total = m_is_50hz ? (m_interlaced ? 629 : 630/2) : (m_interlaced ? 525 : 524/2);
attoseconds_t frame_period = clocks_to_attotime(vert_pix_total * 1530).as_attoseconds();
if (m_columns == 132) // display 1 less filler pixel in 132 char. mode
horiz_pix_total = m_columns * 9; // display 1 less filler pixel in 132 char. mode int horiz_pix_visible = m_columns * (m_columns == 132 ? 9 : 10);
else int horiz_pix_total = m_columns == 132 ? 1530 : 1020;
horiz_pix_total = m_columns * 10; // normal 80 character mode.
visarea.set(0, horiz_pix_total - 1, 0, vert_pix_total - 1); // dot clock is divided by 1.5 in 80 column mode
screen().configure(horiz_pix_total, vert_pix_total, visarea, HZ_TO_ATTOSECONDS((m_interlaced == 0) ? m_frequency : (m_frequency/2) )); screen().set_unscaled_clock(m_columns == 132 ? clock() : clock() * 2 / 3);
rectangle visarea(0, horiz_pix_visible - 1, 0, vert_pix_visible - 1);
screen().configure(horiz_pix_total, vert_pix_total, visarea, frame_period);
if (VERBOSE) LOG("(RECOMPUTE) HPIX: %d (%d) - VPIX: %d (%d)\n", horiz_pix_visible, horiz_pix_total, vert_pix_visible, vert_pix_total);
{ LOG("(RECOMPUTE) FREQUENCY: %f\n", ATTOSECONDS_TO_HZ(frame_period));
printf("\n(RECOMPUTE) HPIX: %d - VPIX: %d", horiz_pix_total, vert_pix_total);
printf("\n(RECOMPUTE) FREQUENCY: %d", (m_interlaced == 0) ? m_frequency : (m_frequency / 2));
if (m_interlaced) if (m_interlaced)
printf("\n(RECOMPUTE) * INTERLACED *"); LOG("(RECOMPUTE) * INTERLACED *\n");
if (m_linedoubler) if (m_linedoubler)
printf("\n(RECOMPUTE) * LINEDOUBLER *"); LOG("(RECOMPUTE) * LINEDOUBLER *\n");
}
} }
@ -236,13 +232,13 @@ WRITE8_MEMBER(vt100_video_device::dc012_w)
if ((offset & 0x100) ) // MHFU is disabled by writing a value to port 010C. if ((offset & 0x100) ) // MHFU is disabled by writing a value to port 010C.
{ {
// if (MHFU_FLAG == true) // if (MHFU_FLAG == true)
// printf("MHFU *** DISABLED *** \n"); // LOG("MHFU *** DISABLED *** \n");
MHFU_FLAG = false; MHFU_FLAG = false;
} }
else else
{ {
// if (MHFU_FLAG == false) // if (MHFU_FLAG == false)
// printf("MHFU ___ENABLED___ %05x \n", space.device().safe_pc()); // LOG("MHFU ___ENABLED___ %05x \n", space.device().safe_pc());
MHFU_FLAG = true; MHFU_FLAG = true;
MHFU_counter = 0; MHFU_counter = 0;
} }
@ -325,7 +321,7 @@ WRITE8_MEMBER(vt100_video_device::dc011_w)
{ {
if (!BIT(data, 5)) if (!BIT(data, 5))
{ {
m_interlaced = 1; m_interlaced = true;
if (!BIT(data, 4)) if (!BIT(data, 4))
m_columns = 80; m_columns = 80;
@ -334,18 +330,9 @@ WRITE8_MEMBER(vt100_video_device::dc011_w)
} }
else else
{ {
m_interlaced = 0; m_interlaced = false;
m_is_50hz = BIT(data, 4);
if (!BIT(data, 4)) m_fill_lines = m_is_50hz ? 5 : 2;
{
m_frequency = 60;
m_fill_lines = 2;
}
else
{
m_frequency = 50;
m_fill_lines = 5;
}
} }
recompute_parameters(); recompute_parameters();
@ -364,17 +351,20 @@ void vt100_video_device::display_char(bitmap_ind16 &bitmap, uint8_t code, int x,
int bit = 0, prevbit, invert = 0, j; int bit = 0, prevbit, invert = 0, j;
int double_width = (display_type == 2) ? 1 : 0; int double_width = (display_type == 2) ? 1 : 0;
for (int i = 0; i < 10; i++) int char_lines = m_linedoubler ? 20 : 10;
for (int i = 0; i < char_lines; i++)
{ {
int yy = y * 10 + i;
switch (display_type) switch (display_type)
{ {
case 0: // bottom half, double height case 0: // bottom half, double height
j = (i >> 1) + 5; break; j = (i >> (m_linedoubler ? 2 : 1)) + 5; break;
case 1: // top half, double height case 1: // top half, double height
j = (i >> 1); break; j = i >> (m_linedoubler ? 2 : 1); break;
case 2: // double width case 2: // double width
case 3: // normal case 3: // normal
j = i; break; j = i >> (m_linedoubler ? 1 : 0); break;
default: j = 0; break; default: j = 0; break;
} }
// modify line since that is how it is stored in rom // modify line since that is how it is stored in rom
@ -396,27 +386,27 @@ void vt100_video_device::display_char(bitmap_ind16 &bitmap, uint8_t code, int x,
bit = BIT((line << b), 7); bit = BIT((line << b), 7);
if (double_width) if (double_width)
{ {
bitmap.pix16(y * 10 + i, x * 20 + b * 2) = (bit | prevbit) ^ invert; bitmap.pix16(yy, x * 20 + b * 2) = (bit | prevbit) ^ invert;
bitmap.pix16(y * 10 + i, x * 20 + b * 2 + 1) = bit ^ invert; bitmap.pix16(yy, x * 20 + b * 2 + 1) = bit ^ invert;
} }
else else
{ {
bitmap.pix16(y * 10 + i, x * 10 + b) = (bit | prevbit) ^ invert; bitmap.pix16(yy, x * 10 + b) = (bit | prevbit) ^ invert;
} }
} }
prevbit = bit; prevbit = bit;
// char interleave is filled with last bit // char interleave is filled with last bit
if (double_width) if (double_width)
{ {
bitmap.pix16(y * 10 + i, x * 20 + 16) = (bit | prevbit) ^ invert; bitmap.pix16(yy, x * 20 + 16) = (bit | prevbit) ^ invert;
bitmap.pix16(y * 10 + i, x * 20 + 17) = bit ^ invert; bitmap.pix16(yy, x * 20 + 17) = bit ^ invert;
bitmap.pix16(y * 10 + i, x * 20 + 18) = bit ^ invert; bitmap.pix16(yy, x * 20 + 18) = bit ^ invert;
bitmap.pix16(y * 10 + i, x * 20 + 19) = bit ^ invert; bitmap.pix16(yy, x * 20 + 19) = bit ^ invert;
} }
else else
{ {
bitmap.pix16(y * 10 + i, x * 10 + 8) = (bit | prevbit) ^ invert; bitmap.pix16(yy, x * 10 + 8) = (bit | prevbit) ^ invert;
bitmap.pix16(y * 10 + i, x * 10 + 9) = bit ^ invert; bitmap.pix16(yy, x * 10 + 9) = bit ^ invert;
} }
} }
} }
@ -436,7 +426,10 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
if (m_read_ram(0) != 0x7f) if (m_read_ram(0) != 0x7f)
return; return;
while (line < (m_height + m_fill_lines)) int vert_charlines_MAX = m_height;
if (m_linedoubler)
vert_charlines_MAX *= 2;
while (line < vert_charlines_MAX)
{ {
code = m_read_ram(addr + xpos); code = m_read_ram(addr + xpos);
if (code == 0x7f) if (code == 0x7f)
@ -459,6 +452,8 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
if (line >= m_fill_lines) if (line >= m_fill_lines)
{ {
ypos++; ypos++;
if (m_linedoubler)
ypos++;
} }
xpos = 0; xpos = 0;
line++; line++;
@ -724,7 +719,9 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c
break; break;
} }
int vert_charlines_MAX = ((m_linedoubler == false) ? m_height : m_height_MAX); int vert_charlines_MAX = m_height;
if (m_linedoubler)
vert_charlines_MAX *= 2;
while (line < vert_charlines_MAX) while (line < vert_charlines_MAX)
{ {
code = m_read_ram(addr + xpos); code = m_read_ram(addr + xpos);

View File

@ -65,8 +65,8 @@ protected:
uint8_t m_height; uint8_t m_height;
uint8_t m_height_MAX; uint8_t m_height_MAX;
uint8_t m_fill_lines; uint8_t m_fill_lines;
uint8_t m_frequency; bool m_is_50hz;
uint8_t m_interlaced; bool m_interlaced;
emu_timer * m_lba7_change_timer; emu_timer * m_lba7_change_timer;
required_region_ptr<uint8_t> m_char_rom; /* character rom region */ required_region_ptr<uint8_t> m_char_rom; /* character rom region */