mirror of
https://github.com/holub/mame
synced 2025-06-17 17:59:05 +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(0x0000, 0x1fff).rom(); // ROM ( 4 * 2K)
|
||||
map(0x2000, 0x2bff).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(0x2000, 0x3fff).ram().share("p_ram"); // Screen and scratch RAM
|
||||
//map(0x3000, 0x3fff).ram(); // AVO Attribute RAM (4 bits wide)
|
||||
// 0x4000, 0x7fff is unassigned
|
||||
map(0x8000, 0x9fff).rom(); // Program memory expansion ROM (4 * 2K)
|
||||
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()
|
||||
{
|
||||
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_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)
|
||||
{
|
||||
uint16_t addr = 0;
|
||||
int line = 0;
|
||||
int xpos = 0;
|
||||
int ypos = 0;
|
||||
uint8_t code;
|
||||
int x = 0;
|
||||
uint8_t scroll_region = 1; // binary 1
|
||||
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)
|
||||
{
|
||||
code = m_read_ram(addr + xpos);
|
||||
uint8_t code = m_read_ram(addr + xpos);
|
||||
if (code == 0x7f)
|
||||
{
|
||||
// end of line, fill empty till end of line
|
||||
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
|
||||
temp = m_read_ram(addr + xpos + 1) * 256 + m_read_ram(addr + xpos + 2);
|
||||
addr = (temp)& 0x1fff;
|
||||
// if A12 is 1 then it is 0x2000 block, if 0 then 0x4000 (AVO)
|
||||
if (addr & 0x1000) addr &= 0xfff; else addr |= 0x2000;
|
||||
// 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;*/
|
||||
scroll_region = (temp >> 15) & 1;
|
||||
display_type = (temp >> 13) & 3;
|
||||
display_type = bitswap<2>((temp >> 13) & 3, 0, 1);
|
||||
if (line >= fill_lines)
|
||||
ypos++;
|
||||
xpos = 0;
|
||||
@ -484,7 +418,8 @@ void vt100_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &cli
|
||||
// display regular char
|
||||
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++;
|
||||
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'
|
||||
|
||||
// ATTRIBUTES: No attributes = 0x0E
|
||||
// 1 = display char. in REVERSE (encoded as 8 in display_type) HIGH ACTIVE
|
||||
// 0 = display char. in BOLD (encoded as 16 in display_type) LOW ACTIVE
|
||||
// 0 = display char. w. BLINK (encoded as 32 in display_type) LOW ACTIVE
|
||||
// 0 = display char. w. UNDERLINE (encoded as 64 in display_type) 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)
|
||||
// 1 = display char. in REVERSE (encoded as 1 in attribute) HIGH ACTIVE
|
||||
// 0 = display char. in BOLD (encoded as 2 in attribute) LOW ACTIVE
|
||||
// 0 = display char. w. BLINK (encoded as 4 in attribute) LOW ACTIVE
|
||||
// 0 = display char. w. UNDERLINE (encoded as 8 in attribute) LOW ACTIVE
|
||||
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)
|
||||
x_preset += x;
|
||||
@ -540,12 +475,6 @@ void rainbow_video_device::display_char(bitmap_ind16 &bitmap, uint8_t code, int
|
||||
int fg_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;
|
||||
|
||||
// * 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);
|
||||
|
||||
bool force_blank;
|
||||
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
|
||||
display_type &= 0x7f; // else activate display.
|
||||
force_blank = false; // else activate display.
|
||||
|
||||
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++)
|
||||
{
|
||||
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 **
|
||||
@ -783,10 +713,10 @@ void rainbow_video_device::video_update(bitmap_ind16 &bitmap, const rectangle &c
|
||||
else
|
||||
{
|
||||
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 -
|
||||
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++;
|
||||
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)
|
||||
{
|
||||
PALETTE(config, m_palette, palette_device::MONOCHROME);
|
||||
}
|
||||
|
||||
void rainbow_video_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
PALETTE(config, m_palette).set_entries(4);
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ protected:
|
||||
// internal state
|
||||
void recompute_parameters();
|
||||
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(lba7_change);
|
||||
virtual void notify_vblank(bool choice) { }
|
||||
@ -101,10 +101,8 @@ public:
|
||||
void palette_select(int choice);
|
||||
|
||||
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 device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(VT100_VIDEO, vt100_video_device)
|
||||
|
Loading…
Reference in New Issue
Block a user