mirror of
https://github.com/holub/mame
synced 2025-07-06 10:29:38 +03:00
saa5050: graphics generator and character rounding
- implemented graphics generator, no longer read from fake ROM - added character rounding - improved control code handling - added ROMs for variants saa5051, saa5053, saa5054, saa5055, saa5056, saa5057
This commit is contained in:
parent
a262490826
commit
876c07fbf5
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder
|
||||
// copyright-holders:Curt Coder, Nigel Barnes
|
||||
/**********************************************************************
|
||||
|
||||
Mullard SAA5050 Teletext Character Generator emulation
|
||||
@ -12,7 +12,6 @@
|
||||
|
||||
TODO:
|
||||
|
||||
- character rounding
|
||||
- remote controller input
|
||||
- boxing
|
||||
|
||||
@ -40,8 +39,8 @@ const device_type SAA5057 = &device_creator<saa5057_device>;
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5050 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5050", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc) )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5050", 0x0140, 0x03c0, BAD_DUMP CRC(6298fc0b) SHA1(ae38e7f51dd33733bacfa896425ca105682b31d6))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -50,8 +49,8 @@ ROM_END
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5051 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5051", 0x0140, 0x08c0, NO_DUMP )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5051", 0x0140, 0x03c0, BAD_DUMP CRC(a770611c) SHA1(9ab9d24b845fe2964fba2f4770d54025d2c8026a))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -60,8 +59,8 @@ ROM_END
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5052 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5052", 0x0140, 0x08c0, BAD_DUMP CRC(cda3bf79) SHA1(cf5ea94459c09001d422dadc212bc970b4b4aa20) )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5052", 0x0140, 0x03c0, BAD_DUMP CRC(2eb76737) SHA1(ec4bc515e28e851a6433f7ca0a11ede0f1d21a68))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -70,8 +69,8 @@ ROM_END
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5053 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5053", 0x0140, 0x08c0, NO_DUMP )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5053", 0x0140, 0x03c0, BAD_DUMP CRC(46288c33) SHA1(1e471a1b5670d7163e9f62d31be7cab0330a07cd))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -80,8 +79,8 @@ ROM_END
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5054 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5054", 0x0140, 0x08c0, NO_DUMP )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5054", 0x0140, 0x03c0, BAD_DUMP CRC(56298472) SHA1(7a273ad7270507dca4ce621fc1e6b51a1ac25085))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -90,8 +89,8 @@ ROM_END
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5055 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5055", 0x0140, 0x08c0, NO_DUMP )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5055", 0x0140, 0x03c0, BAD_DUMP CRC(f95b9c8c) SHA1(c5ce7fe84df6de6a317fa0e87bda413c82c04618))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -100,8 +99,8 @@ ROM_END
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5056 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5056", 0x0140, 0x08c0, NO_DUMP )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5056", 0x0140, 0x03c0, BAD_DUMP CRC(86ab8b85) SHA1(2d1ff08b4dda15cf70832881750a962189455f41))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -110,8 +109,8 @@ ROM_END
|
||||
//-------------------------------------------------
|
||||
|
||||
ROM_START( saa5057 )
|
||||
ROM_REGION( 0xa00, "chargen", 0 )
|
||||
ROM_LOAD( "saa5057", 0x0140, 0x08c0, NO_DUMP )
|
||||
ROM_REGION( 0x500, "chargen", 0 )
|
||||
ROM_LOAD("saa5057", 0x0140, 0x08c0, BAD_DUMP CRC(d6664fb3) SHA1(5a93445dde03066073e2909a935900e5f8439d81))
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -160,6 +159,10 @@ const rom_entry *saa5057_device::device_rom_region() const
|
||||
}
|
||||
|
||||
|
||||
#define ALPHANUMERIC 0x01
|
||||
#define CONTIGUOUS 0x02
|
||||
#define SEPARATED 0x03
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
@ -225,22 +228,25 @@ void saa5050_device::device_start()
|
||||
|
||||
// register for state saving
|
||||
save_item(NAME(m_code));
|
||||
save_item(NAME(m_last_code));
|
||||
save_item(NAME(m_held_char));
|
||||
save_item(NAME(m_char_data));
|
||||
save_item(NAME(m_bit));
|
||||
save_item(NAME(m_color));
|
||||
save_item(NAME(m_ra));
|
||||
save_item(NAME(m_bg));
|
||||
save_item(NAME(m_fg));
|
||||
save_item(NAME(m_prev_col));
|
||||
save_item(NAME(m_graphics));
|
||||
save_item(NAME(m_separated));
|
||||
save_item(NAME(m_conceal));
|
||||
save_item(NAME(m_flash));
|
||||
save_item(NAME(m_boxed));
|
||||
save_item(NAME(m_double_height));
|
||||
save_item(NAME(m_double_height_top_row));
|
||||
save_item(NAME(m_double_height_old));
|
||||
save_item(NAME(m_double_height_bottom_row));
|
||||
save_item(NAME(m_hold));
|
||||
save_item(NAME(m_double_height_prev_row));
|
||||
save_item(NAME(m_hold_char));
|
||||
save_item(NAME(m_hold_clear));
|
||||
save_item(NAME(m_hold_off));
|
||||
save_item(NAME(m_frame_count));
|
||||
}
|
||||
|
||||
@ -252,7 +258,7 @@ void saa5050_device::device_start()
|
||||
void saa5050_device::device_reset()
|
||||
{
|
||||
m_ra = 0;
|
||||
m_double_height_top_row = false;
|
||||
m_double_height = false;
|
||||
m_double_height_bottom_row = false;
|
||||
}
|
||||
|
||||
@ -263,86 +269,175 @@ void saa5050_device::device_reset()
|
||||
|
||||
void saa5050_device::process_control_character(UINT8 data)
|
||||
{
|
||||
m_hold_clear = false;
|
||||
m_hold_off = false;
|
||||
|
||||
switch (data)
|
||||
{
|
||||
case ALPHA_RED:
|
||||
case ALPHA_GREEN:
|
||||
case ALPHA_YELLOW:
|
||||
case ALPHA_BLUE:
|
||||
case ALPHA_MAGENTA:
|
||||
case ALPHA_CYAN:
|
||||
case ALPHA_WHITE:
|
||||
m_graphics = false;
|
||||
m_conceal = false;
|
||||
m_fg = data & 0x07;
|
||||
case ALPHA_RED:
|
||||
case ALPHA_GREEN:
|
||||
case ALPHA_YELLOW:
|
||||
case ALPHA_BLUE:
|
||||
case ALPHA_MAGENTA:
|
||||
case ALPHA_CYAN:
|
||||
case ALPHA_WHITE:
|
||||
m_graphics = false;
|
||||
m_hold_clear = true;
|
||||
m_fg = data & 0x07;
|
||||
set_next_chartype();
|
||||
break;
|
||||
|
||||
case FLASH:
|
||||
m_flash = true;
|
||||
break;
|
||||
|
||||
case STEADY:
|
||||
m_flash = false;
|
||||
break;
|
||||
|
||||
case END_BOX:
|
||||
case START_BOX:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case NORMAL_HEIGHT:
|
||||
case DOUBLE_HEIGHT:
|
||||
m_double_height = !!(data & 1);
|
||||
if (m_double_height) m_double_height_prev_row = true;
|
||||
break;
|
||||
|
||||
case GRAPHICS_RED:
|
||||
case GRAPHICS_GREEN:
|
||||
case GRAPHICS_YELLOW:
|
||||
case GRAPHICS_BLUE:
|
||||
case GRAPHICS_MAGENTA:
|
||||
case GRAPHICS_CYAN:
|
||||
case GRAPHICS_WHITE:
|
||||
m_graphics = true;
|
||||
m_fg = data & 0x07;
|
||||
set_next_chartype();
|
||||
break;
|
||||
|
||||
case CONCEAL_DISPLAY:
|
||||
m_fg = m_prev_col = m_bg;
|
||||
break;
|
||||
|
||||
case CONTIGUOUS_GFX:
|
||||
m_separated = false;
|
||||
set_next_chartype();
|
||||
break;
|
||||
|
||||
case SEPARATED_GFX:
|
||||
m_separated = true;
|
||||
set_next_chartype();
|
||||
break;
|
||||
|
||||
case BLACK_BACKGROUND:
|
||||
m_bg = 0;
|
||||
break;
|
||||
|
||||
case NEW_BACKGROUND:
|
||||
m_bg = m_fg;
|
||||
break;
|
||||
|
||||
case HOLD_GRAPHICS:
|
||||
m_hold_char = true;
|
||||
break;
|
||||
|
||||
case RELEASE_GRAPHICS:
|
||||
m_hold_off = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void saa5050_device::set_next_chartype()
|
||||
{
|
||||
if (m_graphics)
|
||||
{
|
||||
if (m_separated)
|
||||
m_next_chartype = SEPARATED;
|
||||
else
|
||||
m_next_chartype = CONTIGUOUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_next_chartype = ALPHANUMERIC;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_gfx_data - graphics generator
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT16 saa5050_device::get_gfx_data(UINT8 data, offs_t row, bool separated)
|
||||
{
|
||||
UINT16 c = 0;
|
||||
switch (row >> 1)
|
||||
{
|
||||
case 0: case 1:
|
||||
c += (data & 0x01) ? 0xfc0 : 0; // bit 1 top left
|
||||
c += (data & 0x02) ? 0x03f : 0; // bit 2 top right
|
||||
if (separated) c &= 0x3cf;
|
||||
break;
|
||||
|
||||
case FLASH:
|
||||
m_flash = true;
|
||||
case 2:
|
||||
if (separated) break;
|
||||
c += (data & 0x01) ? 0xfc0 : 0; // bit 1 top left
|
||||
c += (data & 0x02) ? 0x03f : 0; // bit 2 top right
|
||||
break;
|
||||
|
||||
case STEADY:
|
||||
m_flash = false;
|
||||
case 3: case 4: case 5:
|
||||
c += (data & 0x04) ? 0xfc0 : 0; // bit 3 middle left
|
||||
c += (data & 0x08) ? 0x03f : 0; // bit 4 middle right
|
||||
if (separated) c &= 0x3cf;
|
||||
break;
|
||||
|
||||
case END_BOX:
|
||||
case START_BOX:
|
||||
// TODO
|
||||
case 6:
|
||||
if (separated) break;
|
||||
c += (data & 0x04) ? 0xfc0 : 0; // bit 3 middle left
|
||||
c += (data & 0x08) ? 0x03f : 0; // bit 4 middle right
|
||||
break;
|
||||
|
||||
case NORMAL_HEIGHT:
|
||||
m_double_height = 0;
|
||||
case 7: case 8:
|
||||
c += (data & 0x10) ? 0xfc0 : 0; // bit 5 bottom left
|
||||
c += (data & 0x40) ? 0x03f : 0; // bit 7 bottom right
|
||||
if (separated) c &= 0x3cf;
|
||||
break;
|
||||
|
||||
case DOUBLE_HEIGHT:
|
||||
if (!m_double_height_bottom_row)
|
||||
{
|
||||
m_double_height_top_row = true;
|
||||
}
|
||||
|
||||
m_double_height = 1;
|
||||
break;
|
||||
|
||||
case GRAPHICS_RED:
|
||||
case GRAPHICS_GREEN:
|
||||
case GRAPHICS_YELLOW:
|
||||
case GRAPHICS_BLUE:
|
||||
case GRAPHICS_MAGENTA:
|
||||
case GRAPHICS_CYAN:
|
||||
case GRAPHICS_WHITE:
|
||||
m_graphics = true;
|
||||
m_conceal = false;
|
||||
m_fg = data & 0x07;
|
||||
break;
|
||||
|
||||
case CONCEAL_DISPLAY:
|
||||
m_conceal = true;
|
||||
break;
|
||||
|
||||
case CONTIGUOUS_GFX:
|
||||
m_separated = false;
|
||||
break;
|
||||
|
||||
case SEPARATED_GFX:
|
||||
m_separated = true;
|
||||
break;
|
||||
|
||||
case BLACK_BACKGROUND:
|
||||
m_bg = 0;
|
||||
break;
|
||||
|
||||
case NEW_BACKGROUND:
|
||||
m_bg = m_fg;
|
||||
break;
|
||||
|
||||
case HOLD_GRAPHICS:
|
||||
m_hold = true;
|
||||
break;
|
||||
|
||||
case RELEASE_GRAPHICS:
|
||||
m_hold = false;
|
||||
case 9:
|
||||
if (separated) break;
|
||||
c += (data & 0x10) ? 0xfc0 : 0; // bit 5 bottom left
|
||||
c += (data & 0x40) ? 0x03f : 0; // bit 7 bottom right
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_rom_data - read rom
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT16 saa5050_device::get_rom_data(UINT8 data, offs_t row)
|
||||
{
|
||||
UINT16 c;
|
||||
if (row < 0 || row >= 20)
|
||||
{
|
||||
c = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = m_char_rom[(data * 10) + (row >> 1)];
|
||||
c = ((c & 0x01) * 0x03) + ((c & 0x02) * 0x06) + ((c & 0x04) * 0x0c) + ((c & 0x08) * 0x18) + ((c & 0x10) * 0x30);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// character_rounding
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT16 saa5050_device::character_rounding(UINT16 a, UINT16 b)
|
||||
{
|
||||
return a | ((a >> 1) & b & ~(b >> 1)) | ((a << 1) & b & ~(b << 1));
|
||||
}
|
||||
|
||||
|
||||
@ -352,23 +447,64 @@ void saa5050_device::process_control_character(UINT8 data)
|
||||
|
||||
void saa5050_device::get_character_data(UINT8 data)
|
||||
{
|
||||
if (m_graphics && (data & 0x20))
|
||||
m_double_height_old = m_double_height;
|
||||
m_prev_col = m_fg;
|
||||
m_curr_chartype = m_next_chartype;
|
||||
|
||||
if (data < 0x20)
|
||||
{
|
||||
data += (data & 0x40) ? 64 : 96;
|
||||
if (m_separated) data += 64;
|
||||
process_control_character(data);
|
||||
if (m_hold_char && m_double_height == m_double_height_old)
|
||||
{
|
||||
data = m_held_char;
|
||||
if (data >= 0x40 && data < 0x60) data = 0x20;
|
||||
m_curr_chartype = m_held_chartype;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = 0x20;
|
||||
}
|
||||
}
|
||||
else if (m_graphics)
|
||||
{
|
||||
m_held_char = data;
|
||||
m_held_chartype = m_curr_chartype;
|
||||
}
|
||||
|
||||
offs_t ra = m_ra;
|
||||
if (m_double_height_old)
|
||||
{
|
||||
ra >>= 1;
|
||||
if (m_double_height_bottom_row) ra += 10;
|
||||
}
|
||||
|
||||
if ((data < 0x20) && m_hold) data = m_last_code;
|
||||
if (m_conceal) data = 0x20;
|
||||
if (m_flash && (m_frame_count > 38)) data = 0x20;
|
||||
if (m_double_height_bottom_row && !m_double_height) data = 0x20;
|
||||
m_last_code = data;
|
||||
|
||||
offs_t ra = m_ra >> 1;
|
||||
if (m_double_height) ra >>= 1;
|
||||
if (m_double_height && m_double_height_bottom_row) ra += 5;
|
||||
if (m_hold_off)
|
||||
{
|
||||
m_hold_char = false;
|
||||
m_held_char = 32;
|
||||
}
|
||||
if (m_hold_clear)
|
||||
{
|
||||
m_held_char = 32;
|
||||
}
|
||||
|
||||
m_char_data = m_char_rom[(data * 10) + ra];
|
||||
if (m_curr_chartype == ALPHANUMERIC || !BIT(data,5))
|
||||
m_char_data = character_rounding(get_rom_data(data, ra), get_rom_data(data, ra + ((ra & 1) ? 1 : -1)));
|
||||
else
|
||||
m_char_data = get_gfx_data(data, ra, (m_curr_chartype == SEPARATED));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// crs_w - character rounding select
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( saa5050_device::crs_w )
|
||||
{
|
||||
m_crs = !(state & 1);
|
||||
}
|
||||
|
||||
|
||||
@ -381,7 +517,6 @@ WRITE_LINE_MEMBER( saa5050_device::dew_w )
|
||||
if (state)
|
||||
{
|
||||
m_ra = 19;
|
||||
m_double_height_top_row = false;
|
||||
|
||||
m_frame_count++;
|
||||
if (m_frame_count > 50) m_frame_count = 0;
|
||||
@ -400,23 +535,27 @@ WRITE_LINE_MEMBER( saa5050_device::lose_w )
|
||||
m_ra++;
|
||||
m_ra %= 20;
|
||||
|
||||
if (m_ra == 19)
|
||||
{
|
||||
if (m_double_height_bottom_row)
|
||||
m_double_height_bottom_row = false;
|
||||
else
|
||||
m_double_height_bottom_row = m_double_height_prev_row;
|
||||
}
|
||||
|
||||
m_fg = 7;
|
||||
m_bg = 0;
|
||||
m_graphics = false;
|
||||
m_separated = false;
|
||||
m_conceal = false;
|
||||
m_flash = false;
|
||||
m_boxed = false;
|
||||
m_hold = false;
|
||||
m_double_height = 0;
|
||||
m_bit = 5;
|
||||
m_last_code = 0x20;
|
||||
|
||||
if (!m_ra)
|
||||
{
|
||||
m_double_height_bottom_row = m_double_height_top_row;
|
||||
m_double_height_top_row = false;
|
||||
}
|
||||
m_hold_char = false;
|
||||
m_held_char = 0x20;
|
||||
m_next_chartype = ALPHANUMERIC;
|
||||
m_held_chartype = ALPHANUMERIC;
|
||||
m_double_height = false;
|
||||
m_double_height_prev_row = false;
|
||||
m_bit = 11;
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +578,6 @@ WRITE_LINE_MEMBER( saa5050_device::f1_w )
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
process_control_character(m_code);
|
||||
get_character_data(m_code);
|
||||
}
|
||||
}
|
||||
@ -453,10 +591,10 @@ WRITE_LINE_MEMBER( saa5050_device::tr6_w )
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
m_color = BIT(m_char_data, m_bit) ? m_fg : m_bg;
|
||||
m_color = BIT(m_char_data, m_bit) ? m_prev_col : m_bg;
|
||||
|
||||
m_bit--;
|
||||
if (m_bit < 0) m_bit = 5;
|
||||
if (m_bit < 0) m_bit = 11;
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,7 +638,7 @@ UINT32 saa5050_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
|
||||
f1_w(1);
|
||||
f1_w(0);
|
||||
|
||||
for (int bit = 0; bit < 6; bit++)
|
||||
for (int bit = 0; bit < 12; bit++)
|
||||
{
|
||||
tr6_w(1);
|
||||
tr6_w(0);
|
||||
@ -516,7 +654,6 @@ UINT32 saa5050_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
|
||||
rgb_t rgb = rgb_t(r, g, b);
|
||||
|
||||
bitmap.pix32(y, x++) = rgb;
|
||||
bitmap.pix32(y, x++) = rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
// optional information overrides
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( crs_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( dew_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( lose_w );
|
||||
void write(UINT8 data);
|
||||
@ -120,6 +121,10 @@ private:
|
||||
};
|
||||
|
||||
void process_control_character(UINT8 data);
|
||||
void set_next_chartype();
|
||||
UINT16 get_gfx_data(UINT8 data, offs_t row, bool separated);
|
||||
UINT16 get_rom_data(UINT8 data, offs_t row);
|
||||
UINT16 character_rounding(UINT16 a, UINT16 b);
|
||||
void get_character_data(UINT8 data);
|
||||
|
||||
required_region_ptr<UINT8> m_char_rom;
|
||||
@ -127,22 +132,29 @@ private:
|
||||
devcb_read8 m_read_d;
|
||||
|
||||
UINT8 m_code;
|
||||
UINT8 m_last_code;
|
||||
UINT8 m_char_data;
|
||||
UINT8 m_held_char;
|
||||
UINT8 m_next_chartype;
|
||||
UINT8 m_curr_chartype;
|
||||
UINT8 m_held_chartype;
|
||||
UINT16 m_char_data;
|
||||
int m_bit;
|
||||
rgb_t m_color;
|
||||
int m_crs;
|
||||
int m_ra;
|
||||
int m_bg;
|
||||
int m_fg;
|
||||
int m_prev_col;
|
||||
bool m_graphics;
|
||||
bool m_separated;
|
||||
bool m_conceal;
|
||||
bool m_flash;
|
||||
bool m_boxed;
|
||||
int m_double_height;
|
||||
bool m_double_height_top_row;
|
||||
bool m_double_height;
|
||||
bool m_double_height_old;
|
||||
bool m_double_height_bottom_row;
|
||||
bool m_hold;
|
||||
bool m_double_height_prev_row;
|
||||
bool m_hold_char;
|
||||
bool m_hold_clear;
|
||||
bool m_hold_off;
|
||||
int m_frame_count;
|
||||
|
||||
int m_cols;
|
||||
@ -248,7 +260,7 @@ extern const device_type SAA5051; // German
|
||||
extern const device_type SAA5052; // Swedish/Finnish
|
||||
extern const device_type SAA5053; // Italian
|
||||
extern const device_type SAA5054; // Belgian
|
||||
extern const device_type SAA5055; // U.S. ASCII
|
||||
extern const device_type SAA5055; // US ASCII
|
||||
extern const device_type SAA5056; // Hebrew
|
||||
extern const device_type SAA5057; // Cyrillic
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
#define ABC806_ATTR_RAM_SIZE 0x800
|
||||
#define ABC806_VIDEO_RAM_SIZE 0x20000
|
||||
|
||||
#define ABC800_CHAR_WIDTH 6
|
||||
#define ABC800_CHAR_WIDTH 12
|
||||
#define ABC800_CCLK ABC800_X01/ABC800_CHAR_WIDTH
|
||||
|
||||
#define SCREEN_TAG "screen"
|
||||
|
@ -40,53 +40,74 @@ unsigned int bbc_state::calculate_video_address(int ma,int ra)
|
||||
{
|
||||
// ma = output from IC2 6845 MA address
|
||||
|
||||
int c0=m_b4_video0; // output from IC32 74LS259 bits 4 and 5
|
||||
int c1=m_b5_video1;
|
||||
int c0 = m_b4_video0; // output from IC32 74LS259 bits 4 and 5
|
||||
int c1 = m_b5_video1;
|
||||
|
||||
/* the 4 bit input port b on IC39 are produced by 4 NAND gates.
|
||||
these NAND gates take their
|
||||
inputs from c0 and c1 (from IC32) and ma12 (from the 6845) */
|
||||
|
||||
/* get bit m12 from the 6845 */
|
||||
int ma12=(ma>>12)&1;
|
||||
int ma12 = BIT(ma,12);
|
||||
|
||||
// 4 bit input B on IC39 74LS283 (4 bit adder)
|
||||
/* 3 input NAND part of IC 36 */
|
||||
int b1=(~(c1 & c0 & ma12)) & 1;
|
||||
/* 2 input NAND part of IC40 (b3 is calculated before b2 and b4 because b3 feed back into b2 and b4) */
|
||||
int b3=(~(c0 & ma12)) & 1;
|
||||
int b3 = (~(c0 & ma12)) & 1;
|
||||
/* 3 input NAND part of IC 36 */
|
||||
int b2=(~(c1 & b3 & ma12)) & 1;
|
||||
int b2 = (~(c1 & b3 & ma12)) & 1;
|
||||
/* 2 input NAND part of IC 27 */
|
||||
int b4=(~(b3 & ma12)) & 1;
|
||||
int b4 = (~(b3 & ma12)) & 1;
|
||||
|
||||
/* inputs port b to IC39 are taken from the NAND gates b1 to b4 */
|
||||
int b=(b1<<0)|(b2<<1)|(b3<<2)|(b4<<3);
|
||||
int b = (b1<<0) | (b2<<1) | (b3<<2) | (b4<<3);
|
||||
|
||||
/* inputs port a to IC39 are MA8 to MA11 from the 6845 */
|
||||
int a=(ma>>8)&0xf;
|
||||
int a = (ma>>8) & 0xf;
|
||||
|
||||
/* IC39 performs the 4 bit add with the carry input set high */
|
||||
int s=(a+b+1)&0xf;
|
||||
int s = (a+b+1) & 0xf;
|
||||
|
||||
/* if MA13 (TTXVDU) is low then IC8 and IC9 are used to calculate
|
||||
the memory location required for the hi res video.
|
||||
if MA13 is hight then IC10 and IC11 are used to calculate the memory location for the teletext chip*/
|
||||
if MA13 is high then IC10 and IC11 are used to calculate the memory location for the teletext chip */
|
||||
unsigned int m;
|
||||
if ((ma>>13)&1)
|
||||
if (BIT(ma,13))
|
||||
{
|
||||
// IC 10 and IC 11
|
||||
m=((ma&0x3ff)|0x3c00)|((s&0x8)<<11);
|
||||
m = ((ma&0x3ff) | 0x3c00) | ((s&0x8)<<11);
|
||||
} else {
|
||||
// IC 8 and IC 9
|
||||
m=((ma&0xff)<<3)|(s<<11)|(ra&0x7);
|
||||
m = ((ma&0xff)<<3) | (s<<11) | (ra&0x7);
|
||||
}
|
||||
if (m_memorySize==16)
|
||||
if (m_memorySize == 16)
|
||||
return m & 0x3fff;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Palette
|
||||
***************************************************************************/
|
||||
|
||||
static const rgb_t bbc_palette[8] =
|
||||
{
|
||||
rgb_t(0x0ff, 0x0ff, 0x0ff),
|
||||
rgb_t(0x000, 0x0ff, 0x0ff),
|
||||
rgb_t(0x0ff, 0x000, 0x0ff),
|
||||
rgb_t(0x000, 0x000, 0x0ff),
|
||||
rgb_t(0x0ff, 0x0ff, 0x000),
|
||||
rgb_t(0x000, 0x0ff, 0x000),
|
||||
rgb_t(0x0ff, 0x000, 0x000),
|
||||
rgb_t(0x000, 0x000, 0x000)
|
||||
};
|
||||
|
||||
PALETTE_INIT_MEMBER(bbc_state, bbc)
|
||||
{
|
||||
palette.set_pen_colors(0, bbc_palette, ARRAY_LENGTH(bbc_palette));
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* VideoULA
|
||||
************************************************************************/
|
||||
@ -101,7 +122,7 @@ void bbc_state::set_pixel_lookup()
|
||||
{
|
||||
for (int i=0; i<256; i++)
|
||||
{
|
||||
m_pixel_bits[i] = (((i>>7)&1)<<3) | (((i>>5)&1)<<2) | (((i>>3)&1)<<1) | (((i>>1)&1)<<0);
|
||||
m_pixel_bits[i] = (BIT(i,7)<<3) | (BIT(i,5)<<2) | (BIT(i,3)<<1) | (BIT(i,1)<<0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,39 +143,36 @@ WRITE8_MEMBER(bbc_state::bbc_videoULA_w)
|
||||
{
|
||||
// Set the control register in the Video ULA
|
||||
case 0:
|
||||
{
|
||||
m_videoULA_Reg=data;
|
||||
m_videoULA_master_cursor_size= (m_videoULA_Reg>>7)&0x01;
|
||||
m_videoULA_width_of_cursor= (m_videoULA_Reg>>5)&0x03;
|
||||
m_videoULA_6845_clock_rate= (m_videoULA_Reg>>4)&0x01;
|
||||
m_videoULA_characters_per_line= (m_videoULA_Reg>>2)&0x03;
|
||||
m_videoULA_teletext_normal_select=(m_videoULA_Reg>>1)&0x01;
|
||||
m_videoULA_flash_colour_select= m_videoULA_Reg &0x01;
|
||||
m_videoULA_Reg = data;
|
||||
m_videoULA_master_cursor_size = (m_videoULA_Reg>>7)&0x01;
|
||||
m_videoULA_width_of_cursor = (m_videoULA_Reg>>5)&0x03;
|
||||
m_videoULA_6845_clock_rate = (m_videoULA_Reg>>4)&0x01;
|
||||
m_videoULA_characters_per_line = (m_videoULA_Reg>>2)&0x03;
|
||||
m_videoULA_teletext_normal_select = (m_videoULA_Reg>>1)&0x01;
|
||||
m_videoULA_flash_colour_select = m_videoULA_Reg &0x01;
|
||||
|
||||
m_videoULA_pallet_lookup=m_videoULA_flash_colour_select?m_videoULA_pallet0:m_videoULA_pallet1;
|
||||
m_videoULA_palette_lookup = m_videoULA_flash_colour_select ? m_videoULA_palette0 : m_videoULA_palette1;
|
||||
|
||||
m_emulation_cursor_size=width_of_cursor_set[m_videoULA_width_of_cursor|(m_videoULA_master_cursor_size<<2)];
|
||||
m_emulation_cursor_size = width_of_cursor_set[m_videoULA_width_of_cursor | (m_videoULA_master_cursor_size<<2)];
|
||||
|
||||
// this is the number of BBC pixels held in each byte
|
||||
if (m_videoULA_teletext_normal_select)
|
||||
{
|
||||
m_pixels_per_byte=6;
|
||||
} else {
|
||||
m_pixels_per_byte=pixels_per_byte_set[m_videoULA_characters_per_line|(m_videoULA_6845_clock_rate<<2)];
|
||||
}
|
||||
m_pixels_per_byte = 12;
|
||||
else
|
||||
m_pixels_per_byte = pixels_per_byte_set[m_videoULA_characters_per_line | (m_videoULA_6845_clock_rate<<2)];
|
||||
|
||||
m_mc6845->set_hpixels_per_column(m_pixels_per_byte);
|
||||
if (m_videoULA_6845_clock_rate)
|
||||
m_mc6845->set_clock(2000000);
|
||||
m_mc6845->set_clock(XTAL_16MHz/8);
|
||||
else
|
||||
m_mc6845->set_clock(1000000);
|
||||
}
|
||||
m_mc6845->set_clock(XTAL_16MHz/16);
|
||||
break;
|
||||
// Set a pallet register in the Video ULA
|
||||
// Set a palette register in the Video ULA
|
||||
case 1:
|
||||
int tpal=(data>>4)&0x0f;
|
||||
int tcol=data&0x0f;
|
||||
m_videoULA_pallet0[tpal]=tcol;
|
||||
m_videoULA_pallet1[tpal]=tcol<8?tcol:tcol^7;
|
||||
int tpal = (data >> 4)&0x0f;
|
||||
int tcol = data&0x0f;
|
||||
m_videoULA_palette0[tpal] = tcol;
|
||||
m_videoULA_palette1[tpal] = tcol<8 ? tcol : tcol^7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -178,21 +196,21 @@ MC6845_UPDATE_ROW( bbc_state::crtc_update_row )
|
||||
//Teletext Latch bit 6 is only passed onto bits 6 on the Teletext chip if DE is true
|
||||
//Teletext Latch bit 7 goes to LOSE on the Teletext chip
|
||||
|
||||
if (((ma>>13)&1)==0)
|
||||
if (BIT(ma,13) == 0)
|
||||
{
|
||||
m_Teletext_Latch=0;
|
||||
m_Teletext_Latch = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Teletext_Latch=(m_BBC_Video_RAM[calculate_video_address(ma+x_pos,ra)]);
|
||||
m_Teletext_Latch = m_BBC_Video_RAM[calculate_video_address(ma+x_pos,ra)];
|
||||
}
|
||||
|
||||
m_trom->write((m_Teletext_Latch&0x3f)|(m_Teletext_Latch&0x40));
|
||||
m_trom->write((m_Teletext_Latch&0x3f) | (m_Teletext_Latch&0x40));
|
||||
|
||||
m_trom->f1_w(1);
|
||||
m_trom->f1_w(0);
|
||||
|
||||
for(int pixelno=0;pixelno<6;pixelno++)
|
||||
for(int pixelno=0; pixelno<12; pixelno++)
|
||||
{
|
||||
m_trom->tr6_w(1);
|
||||
m_trom->tr6_w(0);
|
||||
@ -224,14 +242,14 @@ MC6845_UPDATE_ROW( bbc_state::crtc_update_row )
|
||||
{
|
||||
for(int x_pos=0; x_pos<x_count; x_pos++)
|
||||
{
|
||||
int vmem=calculate_video_address(ma+x_pos,ra);
|
||||
unsigned char i=m_BBC_Video_RAM[vmem];
|
||||
int vmem = calculate_video_address(ma+x_pos,ra);
|
||||
unsigned char i = m_BBC_Video_RAM[vmem];
|
||||
|
||||
for(int pixelno=0;pixelno<m_pixels_per_byte;pixelno++)
|
||||
for(int pixelno=0; pixelno<m_pixels_per_byte; pixelno++)
|
||||
{
|
||||
int col=m_videoULA_pallet_lookup[m_pixel_bits[i]] ^ ((x_pos==cursor_x) ? 7 : 0);
|
||||
bitmap.pix32(y, (x_pos*m_pixels_per_byte)+pixelno)=palette[col];
|
||||
i=(i<<1)|1;
|
||||
int col = m_videoULA_palette_lookup[m_pixel_bits[i]] ^ ((x_pos==cursor_x) ? 7 : 0);
|
||||
bitmap.pix32(y, (x_pos*m_pixels_per_byte)+pixelno) = palette[col];
|
||||
i = (i<<1) | 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -239,9 +257,9 @@ MC6845_UPDATE_ROW( bbc_state::crtc_update_row )
|
||||
{
|
||||
for(int x_pos=0; x_pos<x_count; x_pos++)
|
||||
{
|
||||
for(int pixelno=0;pixelno<m_pixels_per_byte;pixelno++)
|
||||
for(int pixelno=0; pixelno<m_pixels_per_byte; pixelno++)
|
||||
{
|
||||
bitmap.pix32(y, (x_pos*m_pixels_per_byte)+pixelno)=palette[7];
|
||||
bitmap.pix32(y, (x_pos*m_pixels_per_byte)+pixelno) = palette[7];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -259,11 +277,9 @@ WRITE_LINE_MEMBER(bbc_state::bbc_vsync)
|
||||
void bbc_state::bbcbp_setvideoshadow(int vdusel)
|
||||
{
|
||||
if (vdusel)
|
||||
{
|
||||
m_BBC_Video_RAM= m_region_maincpu->base()+0x8000;
|
||||
} else {
|
||||
m_BBC_Video_RAM= m_region_maincpu->base();
|
||||
}
|
||||
m_BBC_Video_RAM = m_region_maincpu->base()+0x8000;
|
||||
else
|
||||
m_BBC_Video_RAM = m_region_maincpu->base();
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
@ -275,13 +291,10 @@ void bbc_state::common_init(int memorySize)
|
||||
{
|
||||
m_emulation_cursor_size = 1;
|
||||
|
||||
m_VideoULA_CR = 7;
|
||||
m_VideoULA_CR_counter = 0;
|
||||
|
||||
set_pixel_lookup();
|
||||
|
||||
m_BBC_Video_RAM = m_region_maincpu->base();
|
||||
m_memorySize=memorySize;
|
||||
m_memorySize = memorySize;
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user