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:
Nigel Barnes 2015-10-21 16:55:10 +01:00
parent a262490826
commit 876c07fbf5
4 changed files with 351 additions and 189 deletions

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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"

View File

@ -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;
}