mirror of
https://github.com/holub/mame
synced 2025-06-18 10:18:57 +03:00
vt100: Implement AVO attributes by merging with Rainbow video emulation
This commit is contained in:
parent
3969a9e9b5
commit
d0fa593c1e
@ -119,9 +119,8 @@ void vt100_state::vt100_mem(address_map &map)
|
|||||||
{
|
{
|
||||||
map.unmap_value_high();
|
map.unmap_value_high();
|
||||||
map(0x0000, 0x1fff).rom(); // ROM ( 4 * 2K)
|
map(0x0000, 0x1fff).rom(); // ROM ( 4 * 2K)
|
||||||
map(0x2000, 0x2bff).ram().share("p_ram"); // Screen and scratch RAM
|
map(0x2000, 0x3fff).ram().share("p_ram"); // Screen and scratch RAM
|
||||||
map(0x2c00, 0x2fff).ram(); // AVO Screen RAM
|
//map(0x3000, 0x3fff).ram(); // AVO Attribute RAM (4 bits wide)
|
||||||
map(0x3000, 0x3fff).ram(); // AVO Attribute RAM (4 bits wide)
|
|
||||||
// 0x4000, 0x7fff is unassigned
|
// 0x4000, 0x7fff is unassigned
|
||||||
map(0x8000, 0x9fff).rom(); // Program memory expansion ROM (4 * 2K)
|
map(0x8000, 0x9fff).rom(); // Program memory expansion ROM (4 * 2K)
|
||||||
map(0xa000, 0xbfff).rom(); // Program memory expansion ROM (1 * 8K)
|
map(0xa000, 0xbfff).rom(); // Program memory expansion ROM (1 * 8K)
|
||||||
|
@ -139,7 +139,9 @@ void vt100_video_device::device_start()
|
|||||||
void vt100_video_device::device_reset()
|
void vt100_video_device::device_reset()
|
||||||
{
|
{
|
||||||
m_palette->set_pen_color(0, 0x00, 0x00, 0x00); // black
|
m_palette->set_pen_color(0, 0x00, 0x00, 0x00); // black
|
||||||
m_palette->set_pen_color(1, 0xff, 0xff, 0xff); // white
|
m_palette->set_pen_color(1, 0xff - 100, 0xff - 100, 0xff - 100); // WHITE (dim)
|
||||||
|
m_palette->set_pen_color(2, 0xff - 50, 0xff - 50, 0xff - 50); // WHITE NORMAL
|
||||||
|
m_palette->set_pen_color(3, 0xff, 0xff, 0xff); // WHITE (brighter)
|
||||||
|
|
||||||
m_height = 25;
|
m_height = 25;
|
||||||
m_height_MAX = 25;
|
m_height_MAX = 25;
|
||||||
@ -363,80 +365,12 @@ WRITE8_MEMBER(vt100_video_device::brightness_w)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void vt100_video_device::display_char(bitmap_ind16 &bitmap, uint8_t code, int x, int y, uint8_t scroll_region, uint8_t display_type)
|
|
||||||
{
|
|
||||||
uint8_t line = 0;
|
|
||||||
int bit = 0, prevbit, invert = 0, j;
|
|
||||||
int double_width = (display_type == 2) ? 1 : 0;
|
|
||||||
|
|
||||||
int char_lines = m_linedoubler ? 20 : 10;
|
|
||||||
for (int i = 0; i < char_lines; i++)
|
|
||||||
{
|
|
||||||
int yy = y * char_lines + i;
|
|
||||||
assert(yy < bitmap.height());
|
|
||||||
|
|
||||||
switch (display_type)
|
|
||||||
{
|
|
||||||
case 0: // bottom half, double height
|
|
||||||
j = (i >> (m_linedoubler ? 2 : 1)) + 5; break;
|
|
||||||
case 1: // top half, double height
|
|
||||||
j = i >> (m_linedoubler ? 2 : 1); break;
|
|
||||||
case 2: // double width
|
|
||||||
case 3: // normal
|
|
||||||
j = i >> (m_linedoubler ? 1 : 0); break;
|
|
||||||
default: j = 0; break;
|
|
||||||
}
|
|
||||||
// modify line since that is how it is stored in rom
|
|
||||||
if (j == 0) j = 15; else j = j - 1;
|
|
||||||
|
|
||||||
line = m_char_rom[(code & 0x7f) * 16 + j];
|
|
||||||
|
|
||||||
if (m_basic_attribute == 1)
|
|
||||||
{
|
|
||||||
if ((code & 0x80) == 0x80)
|
|
||||||
invert = 1;
|
|
||||||
else
|
|
||||||
invert = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int b = 0; b < 8; b++)
|
|
||||||
{
|
|
||||||
prevbit = bit;
|
|
||||||
bit = BIT((line << b), 7);
|
|
||||||
if (double_width)
|
|
||||||
{
|
|
||||||
bitmap.pix16(yy, x * 20 + b * 2) = (bit | prevbit) ^ invert;
|
|
||||||
bitmap.pix16(yy, x * 20 + b * 2 + 1) = bit ^ invert;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bitmap.pix16(yy, x * 10 + b) = (bit | prevbit) ^ invert;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prevbit = bit;
|
|
||||||
// char interleave is filled with last bit
|
|
||||||
if (double_width)
|
|
||||||
{
|
|
||||||
bitmap.pix16(yy, x * 20 + 16) = (bit | prevbit) ^ invert;
|
|
||||||
bitmap.pix16(yy, x * 20 + 17) = bit ^ invert;
|
|
||||||
bitmap.pix16(yy, x * 20 + 18) = bit ^ invert;
|
|
||||||
bitmap.pix16(yy, x * 20 + 19) = bit ^ invert;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bitmap.pix16(yy, x * 10 + 8) = (bit | prevbit) ^ invert;
|
|
||||||
bitmap.pix16(yy, x * 10 + 9) = bit ^ invert;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||||
{
|
{
|
||||||
uint16_t addr = 0;
|
uint16_t addr = 0;
|
||||||
int line = 0;
|
int line = 0;
|
||||||
int xpos = 0;
|
int xpos = 0;
|
||||||
int ypos = 0;
|
int ypos = 0;
|
||||||
uint8_t code;
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
uint8_t scroll_region = 1; // binary 1
|
uint8_t scroll_region = 1; // binary 1
|
||||||
uint8_t display_type = 3; // binary 11
|
uint8_t display_type = 3; // binary 11
|
||||||
@ -454,24 +388,24 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
|
|||||||
}
|
}
|
||||||
while (line < vert_charlines_MAX)
|
while (line < vert_charlines_MAX)
|
||||||
{
|
{
|
||||||
code = m_read_ram(addr + xpos);
|
uint8_t code = m_read_ram(addr + xpos);
|
||||||
if (code == 0x7f)
|
if (code == 0x7f)
|
||||||
{
|
{
|
||||||
// end of line, fill empty till end of line
|
// end of line, fill empty till end of line
|
||||||
if (line >= fill_lines)
|
if (line >= fill_lines)
|
||||||
{
|
{
|
||||||
for (x = xpos; x < ((display_type == 2) ? (m_columns / 2) : m_columns); x++)
|
for (x = xpos; x < ((display_type != 3) ? (m_columns / 2) : m_columns); x++)
|
||||||
{
|
{
|
||||||
display_char(bitmap, code, x, ypos, scroll_region, display_type);
|
display_char(bitmap, code, x, ypos, scroll_region, display_type, false, false, false, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// move to new data
|
// move to new data
|
||||||
temp = m_read_ram(addr + xpos + 1) * 256 + m_read_ram(addr + xpos + 2);
|
temp = m_read_ram(addr + xpos + 1) * 256 + m_read_ram(addr + xpos + 2);
|
||||||
addr = (temp)& 0x1fff;
|
addr = (temp)& 0x1fff;
|
||||||
// if A12 is 1 then it is 0x2000 block, if 0 then 0x4000 (AVO)
|
// if A12 is 1 then it is 0x2000 block, if 0 then 0x4000 (AVO - not actually implemented?)
|
||||||
if (addr & 0x1000) addr &= 0xfff; else addr |= 0x2000;
|
/*if (addr & 0x1000)*/ addr &= 0xfff; /*else addr |= 0x2000;*/
|
||||||
scroll_region = (temp >> 15) & 1;
|
scroll_region = (temp >> 15) & 1;
|
||||||
display_type = (temp >> 13) & 3;
|
display_type = bitswap<2>((temp >> 13) & 3, 0, 1);
|
||||||
if (line >= fill_lines)
|
if (line >= fill_lines)
|
||||||
ypos++;
|
ypos++;
|
||||||
xpos = 0;
|
xpos = 0;
|
||||||
@ -484,7 +418,8 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
|
|||||||
// display regular char
|
// display regular char
|
||||||
if (line >= fill_lines)
|
if (line >= fill_lines)
|
||||||
{
|
{
|
||||||
display_char(bitmap, code, xpos, ypos, scroll_region, display_type);
|
uint8_t attr = m_read_ram(0x1000 + addr + xpos);
|
||||||
|
display_char(bitmap, code & 0x7f, xpos, ypos, scroll_region, display_type, BIT(code, 7), !BIT(attr, 2), !BIT(attr, 0), !BIT(attr, 1), false);
|
||||||
}
|
}
|
||||||
xpos++;
|
xpos++;
|
||||||
if (xpos > m_columns)
|
if (xpos > m_columns)
|
||||||
@ -515,11 +450,11 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
|
|||||||
// LINE ATTRIBUTE 'double_height' always is interpreted as 'double width + double height'
|
// LINE ATTRIBUTE 'double_height' always is interpreted as 'double width + double height'
|
||||||
|
|
||||||
// ATTRIBUTES: No attributes = 0x0E
|
// ATTRIBUTES: No attributes = 0x0E
|
||||||
// 1 = display char. in REVERSE (encoded as 8 in display_type) HIGH ACTIVE
|
// 1 = display char. in REVERSE (encoded as 1 in attribute) HIGH ACTIVE
|
||||||
// 0 = display char. in BOLD (encoded as 16 in display_type) LOW ACTIVE
|
// 0 = display char. in BOLD (encoded as 2 in attribute) LOW ACTIVE
|
||||||
// 0 = display char. w. BLINK (encoded as 32 in display_type) LOW ACTIVE
|
// 0 = display char. w. BLINK (encoded as 4 in attribute) LOW ACTIVE
|
||||||
// 0 = display char. w. UNDERLINE (encoded as 64 in display_type) LOW ACTIVE
|
// 0 = display char. w. UNDERLINE (encoded as 8 in attribute) LOW ACTIVE
|
||||||
void rainbow_video_device::display_char(bitmap_ind16 &bitmap, uint8_t code, int x, int y, uint8_t scroll_region, uint8_t display_type)
|
void vt100_video_device::display_char(bitmap_ind16 &bitmap, uint8_t code, int x, int y, uint8_t scroll_region, uint8_t display_type, bool invert, bool bold, bool blink, bool underline, bool blank)
|
||||||
{
|
{
|
||||||
uint16_t x_preset = x << 3; // x_preset = x * 9 (= 132 column mode)
|
uint16_t x_preset = x << 3; // x_preset = x * 9 (= 132 column mode)
|
||||||
x_preset += x;
|
x_preset += x;
|
||||||
@ -540,12 +475,6 @@ void rainbow_video_device::display_char(bitmap_ind16 &bitmap, uint8_t code, int
|
|||||||
int fg_intensity;
|
int fg_intensity;
|
||||||
int back_intensity, back_default_intensity;
|
int back_intensity, back_default_intensity;
|
||||||
|
|
||||||
int invert = (display_type & 8) ? 1 : 0; // REVERSE
|
|
||||||
int bold = (display_type & 16) ? 0 : 1; // BIT 4
|
|
||||||
int blink = (display_type & 32) ? 0 : 1; // BIT 5
|
|
||||||
int underline = (display_type & 64) ? 0 : 1; // BIT 6
|
|
||||||
bool blank = (display_type & 128) ? true : false; // BIT 7
|
|
||||||
|
|
||||||
display_type = display_type & 3;
|
display_type = display_type & 3;
|
||||||
|
|
||||||
// * SCREEN ATTRIBUTES (see VT-180 manual 6-30) *
|
// * SCREEN ATTRIBUTES (see VT-180 manual 6-30) *
|
||||||
@ -746,17 +675,18 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c
|
|||||||
{
|
{
|
||||||
code = m_read_ram(addr + xpos);
|
code = m_read_ram(addr + xpos);
|
||||||
|
|
||||||
|
bool force_blank;
|
||||||
if (code == 0x00) // TODO: investigate side effect on regular zero character!
|
if (code == 0x00) // TODO: investigate side effect on regular zero character!
|
||||||
display_type |= 0x80; // DEFAULT: filler chars (till end of line) and empty lines (00) will be blanked
|
force_blank = true; // DEFAULT: filler chars (till end of line) and empty lines (00) will be blanked
|
||||||
else
|
else
|
||||||
display_type &= 0x7f; // else activate display.
|
force_blank = false; // else activate display.
|
||||||
|
|
||||||
if (code == 0xff) // end of line, fill empty till end of line
|
if (code == 0xff) // end of line, fill empty till end of line
|
||||||
{
|
{
|
||||||
// HINT: display_type is already shifted! All except 3 is DOUBLE WIDTH 40 or 66 chars per line
|
// All except 3 is DOUBLE WIDTH 40 or 66 chars per line
|
||||||
for (x = xpos; x < ((display_type != 3) ? (m_columns / 2) : m_columns); x++)
|
for (x = xpos; x < ((display_type != 3) ? (m_columns / 2) : m_columns); x++)
|
||||||
{
|
{
|
||||||
display_char(bitmap, code, x, ypos, scroll_region, display_type | 0x80);
|
display_char(bitmap, code, x, ypos, scroll_region, display_type, false, false, false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LINE ATTRIBUTE - valid for all chars on next line ** DO NOT SHUFFLE **
|
// LINE ATTRIBUTE - valid for all chars on next line ** DO NOT SHUFFLE **
|
||||||
@ -783,10 +713,10 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
attr_addr = 0x1000 | ((addr + xpos) & 0x0fff);
|
attr_addr = 0x1000 | ((addr + xpos) & 0x0fff);
|
||||||
temp = (m_read_ram(attr_addr) & 15) << 3; // get character attributes
|
temp = (m_read_ram(attr_addr) & 15); // get character attributes
|
||||||
|
|
||||||
// see 'display_char' for an explanation of attribute encoding -
|
// see 'display_char' for an explanation of attribute encoding -
|
||||||
display_char(bitmap, code, xpos, ypos, scroll_region, display_type | temp);
|
display_char(bitmap, code, xpos, ypos, scroll_region, display_type, BIT(temp, 0), !BIT(temp, 1), !BIT(temp, 2), !BIT(temp, 3), force_blank);
|
||||||
|
|
||||||
xpos++;
|
xpos++;
|
||||||
if (xpos > m_columns)
|
if (xpos > m_columns)
|
||||||
@ -918,11 +848,6 @@ TIMER_CALLBACK_MEMBER(vt100_video_device::lba3_change)
|
|||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void vt100_video_device::device_add_mconfig(machine_config &config)
|
void vt100_video_device::device_add_mconfig(machine_config &config)
|
||||||
{
|
|
||||||
PALETTE(config, m_palette, palette_device::MONOCHROME);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rainbow_video_device::device_add_mconfig(machine_config &config)
|
|
||||||
{
|
{
|
||||||
PALETTE(config, m_palette).set_entries(4);
|
PALETTE(config, m_palette).set_entries(4);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ protected:
|
|||||||
// internal state
|
// internal state
|
||||||
void recompute_parameters();
|
void recompute_parameters();
|
||||||
void vblank_callback(screen_device &screen, bool state);
|
void vblank_callback(screen_device &screen, bool state);
|
||||||
virtual void display_char(bitmap_ind16 &bitmap, uint8_t code, int x, int y, uint8_t scroll_region, uint8_t display_type);
|
void display_char(bitmap_ind16 &bitmap, uint8_t code, int x, int y, uint8_t scroll_region, uint8_t display_type, bool invert, bool bold, bool blink, bool underline, bool blank);
|
||||||
TIMER_CALLBACK_MEMBER(lba3_change);
|
TIMER_CALLBACK_MEMBER(lba3_change);
|
||||||
TIMER_CALLBACK_MEMBER(lba7_change);
|
TIMER_CALLBACK_MEMBER(lba7_change);
|
||||||
virtual void notify_vblank(bool choice) { }
|
virtual void notify_vblank(bool choice) { }
|
||||||
@ -101,10 +101,8 @@ public:
|
|||||||
void palette_select(int choice);
|
void palette_select(int choice);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void display_char(bitmap_ind16 &bitmap, uint8_t code, int x, int y, uint8_t scroll_region, uint8_t display_type) override;
|
|
||||||
virtual void notify_vblank(bool choice) override;
|
virtual void notify_vblank(bool choice) override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
virtual void device_add_mconfig(machine_config &config) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_DEVICE_TYPE(VT100_VIDEO, vt100_video_device)
|
DECLARE_DEVICE_TYPE(VT100_VIDEO, vt100_video_device)
|
||||||
|
Loading…
Reference in New Issue
Block a user