Rewrote the SAA5050 Teletext character generator. Removed saa505x.c which was used by bbc.c, and refactored all drivers to use the new implementation. [Curt Coder]

This commit is contained in:
Curt Coder 2012-09-14 16:37:26 +00:00
parent 002948d06e
commit aed1c5bf74
20 changed files with 730 additions and 4329 deletions

2
.gitattributes vendored
View File

@ -7442,8 +7442,6 @@ src/mess/video/psion.c svneol=native#text/plain
src/mess/video/radio86.c svneol=native#text/plain
src/mess/video/rm380z.c svneol=native#text/plain
src/mess/video/rmnimbus.c svneol=native#text/plain
src/mess/video/saa505x.c svneol=native#text/plain
src/mess/video/saa505x.h svneol=native#text/plain
src/mess/video/samcoupe.c svneol=native#text/plain
src/mess/video/sapi1.c svneol=native#text/plain
src/mess/video/special.c svneol=native#text/plain

View File

@ -1,394 +1,153 @@
/***************************************************************************
/**********************************************************************
saa5050.c
Mullard SAA5050 Teletext Character Generator emulation
Functions to emulate the
SAA5050 - Teletext Character Generator.
http://www.bighole.nl/pub/mirror/homepage.ntlworld.com/kryten_droid/teletext/spec/teletext_spec_1974.htm
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
**********************************************************************/
/*
TODO:
- Implement BOX and dirtybuffer
- Add support for non-English version (SAA505x), possibly merging
src/mess/video/saa505x.c unsed by bbc.c in MESS
- Investigate why supporting code 0 behavior breaks p2000t vscroll
in MESS (but not supporting breaks malzak title background)
- x,y sizes should probably be calculated from the screen parameters
rather than passed in the device interface
***************************************************************************/
- character rounding
- remote controller input
- boxing
#include "emu.h"
#include "video/saa5050.h"
*/
#define SAA5050_DBLHI 0x0001
#define SAA5050_SEPGR 0x0002
#define SAA5050_FLASH 0x0004
#define SAA5050_BOX 0x0008
#define SAA5050_GRAPH 0x0010
#define SAA5050_CONCEAL 0x0020
#define SAA5050_HOLDGR 0x0040
#define SAA5050_BLACK 0
#define SAA5050_WHITE 7
#include "saa5050.h"
typedef struct _saa5050_state saa5050_state;
struct _saa5050_state
{
device_t *screen;
int gfxnum;
int x, y;
int size;
int rev;
UINT8 * videoram;
UINT16 flags;
UINT8 forecol;
UINT8 backcol;
UINT8 prvcol;
UINT8 prvchr;
INT8 frame_count;
};
/*************************************
*
* Inline functions
*
*************************************/
INLINE saa5050_state *get_safe_token( device_t *device )
{
assert(device != NULL);
assert(device->type() == SAA5050);
return (saa5050_state *)downcast<saa5050_device *>(device)->token();
}
INLINE const saa5050_interface *get_interface( device_t *device )
{
assert(device != NULL);
assert((device->type() == SAA5050));
return (const saa5050_interface *) device->static_config();
}
/*************************************
*
* Graphics definitions
*
*************************************/
static const gfx_layout saa5050_charlayout =
{
6, 10,
256,
1,
{ 0 },
{ 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8,
5*8, 6*8, 7*8, 8*8, 9*8 },
8 * 10
};
static const gfx_layout saa5050_hilayout =
{
6, 10,
256,
1,
{ 0 },
{ 2, 3, 4, 5, 6, 7 },
{ 0*8, 0*8, 1*8, 1*8, 2*8,
2*8, 3*8, 3*8, 4*8, 4*8 },
8 * 10
};
static const gfx_layout saa5050_lolayout =
{
6, 10,
256,
1,
{ 0 },
{ 2, 3, 4, 5, 6, 7 },
{ 5*8, 5*8, 6*8, 6*8, 7*8,
7*8, 8*8, 8*8, 9*8, 9*8 },
8 * 10
};
GFXDECODE_START( saa5050 )
GFXDECODE_ENTRY( "gfx1", 0x0000, saa5050_charlayout, 0, 64 )
GFXDECODE_ENTRY( "gfx1", 0x0000, saa5050_hilayout, 0, 64 )
GFXDECODE_ENTRY( "gfx1", 0x0000, saa5050_lolayout, 0, 64 )
GFXDECODE_END
/*************************************
*
* Palette initialization
*
*************************************/
static const UINT8 saa5050_colors[8 * 3] =
{
0x00, 0x00, 0x00, /* black */
0xff, 0x00, 0x00, /* red */
0x00, 0xff, 0x00, /* green */
0xff, 0xff, 0x00, /* yellow */
0x00, 0x00, 0xff, /* blue */
0xff, 0x00, 0xff, /* magenta */
0x00, 0xff, 0xff, /* cyan */
0xff, 0xff, 0xff /* white */
};
static const UINT16 saa5050_palette[64 * 2] = /* bgnd, fgnd */
{
0,1, 0,1, 0,2, 0,3, 0,4, 0,5, 0,6, 0,7,
1,0, 1,1, 1,2, 1,3, 1,4, 1,5, 1,6, 1,7,
2,0, 2,1, 2,2, 2,3, 2,4, 2,5, 2,6, 2,7,
3,0, 3,1, 3,2, 3,3, 3,4, 3,5, 3,6, 3,7,
4,0, 4,1, 4,2, 4,3, 4,4, 4,5, 4,6, 4,7,
5,0, 5,1, 5,2, 5,3, 5,4, 5,5, 5,6, 5,7,
6,0, 6,1, 6,2, 6,3, 6,4, 6,5, 6,6, 6,7,
7,0, 7,1, 7,2, 7,3, 7,4, 7,5, 7,6, 7,7
};
PALETTE_INIT( saa5050 )
{
UINT8 i, r, g, b;
machine.colortable = colortable_alloc(machine, 8);
for ( i = 0; i < 8; i++ )
{
r = saa5050_colors[i * 3];
g = saa5050_colors[i * 3 + 1];
b = saa5050_colors[i * 3 + 2];
colortable_palette_set_color(machine.colortable, i, MAKE_RGB(r, g, b));
}
for (i = 0; i < 128; i++)
colortable_entry_set_value(machine.colortable, i, saa5050_palette[i]);
}
/*************************************
*
* Videoram access handlers
*
*************************************/
WRITE8_DEVICE_HANDLER( saa5050_videoram_w )
{
saa5050_state *saa5050 = get_safe_token(device);
saa5050->videoram[offset] = data;
}
READ8_DEVICE_HANDLER( saa5050_videoram_r )
{
saa5050_state *saa5050 = get_safe_token(device);
return saa5050->videoram[offset];
}
/*************************************
*
* Emulation
*
*************************************/
/* this should probably be put at the end of saa5050 update,
but p2000t in MESS does not seem to currently support it.
Hence, we leave it independent for the moment */
void saa5050_frame_advance( device_t *device )
{
saa5050_state *saa5050 = get_safe_token(device);
saa5050->frame_count++;
if (saa5050->frame_count > 50)
saa5050->frame_count = 0;
}
void saa5050_update( device_t *device, bitmap_ind16 &bitmap, const rectangle &cliprect )
{
saa5050_state *saa5050 = get_safe_token(device);
int code, colour;
int sx, sy, ssy;
for (sy = 0; sy <= saa5050->y; sy++)
{
bool dblhi = false;
/* Set start of line state */
saa5050->flags = 0;
saa5050->prvchr = 32;
saa5050->forecol = SAA5050_WHITE;
saa5050->prvcol = SAA5050_WHITE;
saa5050->backcol = SAA5050_BLACK;
/* should we go in reverse order? */
ssy = saa5050->rev ? saa5050->y - sy : sy;
for (sx = 0; sx < saa5050->x; sx++)
{
int blank = 0;
code = saa5050->videoram[ssy * saa5050->size + sx];
if (code < 32)
{
switch (code)
{
case 0x00:
// Temporary hack until proper docs are found
if (saa5050->rev) // This is not ok, but it is done only in case of malzak
blank = 1; // code 0x00 should not display anything, unless HOLDGR is set
break;
case 0x01: case 0x02: case 0x03: case 0x04:
case 0x05: case 0x06: case 0x07:
saa5050->prvcol = saa5050->forecol = code;
saa5050->flags &= ~(SAA5050_GRAPH | SAA5050_CONCEAL);
break;
case 0x11: case 0x12: case 0x13: case 0x14:
case 0x15: case 0x16: case 0x17:
saa5050->prvcol = (saa5050->forecol = (code & 0x07));
saa5050->flags &= ~SAA5050_CONCEAL;
saa5050->flags |= SAA5050_GRAPH;
break;
case 0x08:
saa5050->flags |= SAA5050_FLASH;
break;
case 0x09:
saa5050->flags &= ~SAA5050_FLASH;
break;
case 0x0a:
saa5050->flags |= SAA5050_BOX;
break;
case 0x0b:
saa5050->flags &= ~SAA5050_BOX;
break;
case 0x0c:
saa5050->flags &= ~SAA5050_DBLHI;
break;
case 0x0d:
saa5050->flags |= SAA5050_DBLHI;
dblhi = true;
break;
case 0x18:
saa5050->flags |= SAA5050_CONCEAL;
break;
case 0x19:
saa5050->flags |= SAA5050_SEPGR;
break;
case 0x1a:
saa5050->flags &= ~SAA5050_SEPGR;
break;
case 0x1c:
saa5050->backcol = SAA5050_BLACK;
break;
case 0x1d:
saa5050->backcol = saa5050->prvcol;
break;
case 0x1e:
saa5050->flags |= SAA5050_HOLDGR;
break;
case 0x1f:
saa5050->flags &= ~SAA5050_HOLDGR;
break;
}
if (saa5050->flags & SAA5050_HOLDGR)
code = saa5050->prvchr;
else
code = 32;
}
if (code & 0x80)
colour = (saa5050->forecol << 3) | saa5050->backcol;
else
colour = saa5050->forecol | (saa5050->backcol << 3);
if (saa5050->flags & SAA5050_CONCEAL)
code = 32;
else if ((saa5050->flags & SAA5050_FLASH) && (saa5050->frame_count > 38))
code = 32;
else
{
saa5050->prvchr = code;
if ((saa5050->flags & SAA5050_GRAPH) && (code & 0x20))
{
code += (code & 0x40) ? 64 : 96;
if (saa5050->flags & SAA5050_SEPGR)
code += 64;
}
}
if((blank == 0) || (saa5050->flags & SAA5050_HOLDGR))
{
if (saa5050->flags & SAA5050_DBLHI)
{
drawgfxzoom_opaque(bitmap, cliprect, saa5050->screen->machine().gfx[saa5050->gfxnum + 1], code & 0x7f, colour, 0, 0, sx * 12, ssy * 20, 0x20000, 0x20000);
drawgfxzoom_opaque(bitmap, cliprect, saa5050->screen->machine().gfx[saa5050->gfxnum + 2], code & 0x7f, colour, 0, 0, sx * 12, (ssy + 1) * 20, 0x20000, 0x20000);
}
else
{
drawgfxzoom_opaque(bitmap, cliprect, saa5050->screen->machine().gfx[saa5050->gfxnum + 0], code & 0x7f, colour, 0, 0, sx * 12, ssy * 20, 0x20000, 0x20000);
}
}
}
if (dblhi)
{
sy++;
}
}
}
/*****************************************************************************
DEVICE INTERFACE
*****************************************************************************/
static DEVICE_START( saa5050 )
{
saa5050_state *saa5050 = get_safe_token(device);
const saa5050_interface *intf = get_interface(device);
saa5050->screen = device->machine().device(intf->screen);
saa5050->gfxnum = intf->gfxnum;
saa5050->x = intf->x;
saa5050->y = intf->y;
saa5050->size = intf->size;
saa5050->rev = intf->rev;
saa5050->videoram = auto_alloc_array(device->machine(), UINT8, 0x800);
device->save_pointer(NAME(saa5050->videoram), 0x800);
device->save_item(NAME(saa5050->flags));
device->save_item(NAME(saa5050->forecol));
device->save_item(NAME(saa5050->backcol));
device->save_item(NAME(saa5050->prvcol));
device->save_item(NAME(saa5050->prvchr));
device->save_item(NAME(saa5050->frame_count));
}
static DEVICE_RESET( saa5050 )
{
saa5050_state *saa5050 = get_safe_token(device);
memset(saa5050->videoram, 0x00, 0x800);
saa5050->flags = 0;
saa5050->forecol = SAA5050_WHITE;
saa5050->backcol = SAA5050_BLACK;
saa5050->prvcol = SAA5050_WHITE;
saa5050->prvchr = 32;
saa5050->frame_count = 0;
}
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type SAA5050 = &device_creator<saa5050_device>;
const device_type SAA5052 = &device_creator<saa5052_device>;
//-------------------------------------------------
// ROM( saa5050 )
//-------------------------------------------------
ROM_START( saa5050 )
ROM_REGION( 0x10000, "chargen", 0 )
ROM_LOAD( "saa5050", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc) )
ROM_END
//-------------------------------------------------
// ROM( saa5052 )
//-------------------------------------------------
ROM_START( saa5052 )
ROM_REGION( 0x10000, "chargen", 0 )
ROM_LOAD( "saa5052", 0x0140, 0x08c0, BAD_DUMP CRC(cda3bf79) SHA1(cf5ea94459c09001d422dadc212bc970b4b4aa20) )
ROM_END
//-------------------------------------------------
// rom_region - device-specific ROM region
//-------------------------------------------------
const rom_entry *saa5050_device::device_rom_region() const
{
switch (m_variant)
{
default: return ROM_NAME( saa5050 );
case TYPE_5052: return ROM_NAME( saa5052 );
}
}
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
enum
{
NUL = 0,
ALPHA_RED,
ALPHA_GREEN,
ALPHA_YELLOW,
ALPHA_BLUE,
ALPHA_MAGENTA,
ALPHA_CYAN,
ALPHA_WHITE,
FLASH,
STEADY,
END_BOX,
START_BOX,
NORMAL_HEIGHT,
DOUBLE_HEIGHT,
S0,
S1,
DLE,
GRAPHICS_RED,
GRAPHICS_GREEN,
GRAPHICS_YELLOW,
GRAPHICS_BLUE,
GRAPHICS_MAGENTA,
GRAPHICS_CYAN,
GRAPHICS_WHITE,
CONCEAL_DISPLAY,
CONTIGUOUS_GFX,
SEPARATED_GFX,
ESC,
BLACK_BACKGROUND,
NEW_BACKGROUND,
HOLD_GRAPHICS,
RELEASE_GRAPHICS
};
static const rgb_t PALETTE[] =
{
RGB_BLACK,
MAKE_RGB(0xff, 0x00, 0x00),
MAKE_RGB(0x00, 0xff, 0x00),
MAKE_RGB(0xff, 0xff, 0x00),
MAKE_RGB(0x00, 0x00, 0xff),
MAKE_RGB(0xff, 0x00, 0xff),
MAKE_RGB(0x00, 0xff, 0xff),
RGB_WHITE
};
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// saa5050_device - constructor
//-------------------------------------------------
saa5050_device::saa5050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant)
: device_t(mconfig, type, name, tag, owner, clock),
m_frame_count(0),
m_variant(variant)
{
}
saa5050_device::saa5050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, SAA5050, "SAA5050", tag, owner, clock)
: device_t(mconfig, SAA5050, "SAA5050", tag, owner, clock),
m_frame_count(0),
m_variant(TYPE_5050)
{
m_token = global_alloc_array_clear(UINT8, sizeof(saa5050_state));
}
saa5052_device::saa5052_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: saa5050_device(mconfig, SAA5052, "SAA5052", tag, owner, clock, TYPE_5052)
{
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
@ -397,24 +156,324 @@ saa5050_device::saa5050_device(const machine_config &mconfig, const char *tag, d
void saa5050_device::device_config_complete()
{
// inherit a copy of the static code
const saa5050_interface *intf = reinterpret_cast<const saa5050_interface *>(static_config());
if (intf != NULL)
*static_cast<saa5050_interface *>(this) = *intf;
// or initialize to defaults if none provided
else
{
memset(&m_in_d_cb, 0, sizeof(m_in_d_cb));
}
switch (m_variant)
{
default: m_shortname = "saa5050"; break;
case TYPE_5052: m_shortname = "saa5052"; break;
}
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void saa5050_device::device_start()
{
DEVICE_START_NAME( saa5050 )(this);
// resolve callbacks
m_in_d_func.resolve(m_in_d_cb, *this);
// find memory regions
m_char_rom = memregion("chargen")->base();
// register for state saving
save_item(NAME(m_code));
save_item(NAME(m_last_code));
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_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_bottom_row));
save_item(NAME(m_hold));
save_item(NAME(m_frame_count));
save_item(NAME(m_variant));
}
//-------------------------------------------------
// device_reset - device-specific reset
// process_control_character -
//-------------------------------------------------
void saa5050_device::device_reset()
void saa5050_device::process_control_character(UINT8 data)
{
DEVICE_RESET_NAME( saa5050 )(this);
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;
break;
case FLASH:
m_flash = true;
break;
case STEADY:
m_flash = false;
break;
case END_BOX:
case START_BOX:
// TODO
break;
case NORMAL_HEIGHT:
m_double_height = 0;
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;
break;
}
}
//-------------------------------------------------
// get_character_data -
//-------------------------------------------------
void saa5050_device::get_character_data(UINT8 data)
{
if (m_graphics && (data & 0x20))
{
data += (data & 0x40) ? 64 : 96;
if (m_separated) data += 64;
}
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;
offs_t char_rom_addr = (data * 10) + ra;
m_char_data = m_char_rom[char_rom_addr];
}
//-------------------------------------------------
// dew_w - data entry window
//-------------------------------------------------
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;
}
}
//-------------------------------------------------
// lose_w - load output shift register enable
//-------------------------------------------------
WRITE_LINE_MEMBER( saa5050_device::lose_w )
{
if (state)
{
m_ra++;
m_ra %= 20;
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;
}
}
}
//-------------------------------------------------
// write - character data write
//-------------------------------------------------
void saa5050_device::write(UINT8 data)
{
m_code = data & 0x7f;
}
//-------------------------------------------------
// f1_w - character clock
//-------------------------------------------------
WRITE_LINE_MEMBER( saa5050_device::f1_w )
{
if (state)
{
process_control_character(m_code);
get_character_data(m_code);
}
}
//-------------------------------------------------
// tr6_w - pixel clock
//-------------------------------------------------
WRITE_LINE_MEMBER( saa5050_device::tr6_w )
{
if (state)
{
m_color = BIT(m_char_data, m_bit) ? m_fg : m_bg;
m_bit--;
if (m_bit < 0) m_bit = 5;
}
}
//-------------------------------------------------
// get_rgb - get output color
//-------------------------------------------------
int saa5050_device::get_rgb()
{
return m_color;
}
//-------------------------------------------------
// screen_update -
//-------------------------------------------------
UINT32 saa5050_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
dew_w(1);
dew_w(0);
for (int y = 0; y < m_rows * 20; y++)
{
int sy = y / 20;
int x = 0;
lose_w(1);
lose_w(0);
int ssy = m_double_height_bottom_row ? sy - 1 : sy;
offs_t video_ram_addr = ssy * m_size;
for (int sx = 0; sx < m_cols; sx++)
{
UINT8 code = m_in_d_func(video_ram_addr++);
write(code & 0x7f);
f1_w(1);
f1_w(0);
for (int bit = 0; bit < 6; bit++)
{
tr6_w(1);
tr6_w(0);
int color = get_rgb();
if (BIT(code, 7)) color ^= 0x07;
int r = BIT(color, 0) * 0xff;
int g = BIT(color, 1) * 0xff;
int b = BIT(color, 2) * 0xff;
rgb_t rgb = MAKE_RGB(r, g, b);
bitmap.pix32(y, x++) = rgb;
bitmap.pix32(y, x++) = rgb;
}
}
}
return 0;
}

View File

@ -1,73 +1,152 @@
/*****************************************************************************
*
* video/saa5050.h
*
* SAA5050
*
****************************************************************************/
/**********************************************************************
#ifndef __SAA5050_H__
#define __SAA5050_H__
Mullard SAA5050 Teletext Character Generator emulation
#include "devlegcy.h"
Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
#define SAA5050_VBLANK 2500
**********************************************************************
_____ _____
Vss 1 |* \_/ | 28 DE
_SI 2 | | 27 PO
_DATA 3 | | 26 LOSE
D1 4 | SAA5050 | 25 BLAN
D2 5 | SAA5051 | 24 R
D3 6 | SAA5052 | 23 G
D4 7 | SAA5053 | 22 B
D5 8 | SAA5054 | 21 Y
D6 9 | SAA5055 | 20 F1
D7 10 | SAA5056 | 19 TR6
DLIM 11 | SAA5057 | 18 Vdd
_GLR 12 | | 17 N/C
DEW 13 | | 16 _TLC
CRS 14 |_____________| 15 _BCS
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
**********************************************************************/
typedef struct _saa5050_interface saa5050_interface;
struct _saa5050_interface
#pragma once
#ifndef __SAA5050__
#define __SAA5050__
#include "emu.h"
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
#define MCFG_SAA5050_ADD(_tag, _clock, _config) \
MCFG_DEVICE_ADD(_tag, SAA5050, _clock) \
MCFG_DEVICE_CONFIG(_config)
#define MCFG_SAA5052_ADD(_tag, _clock, _config) \
MCFG_DEVICE_ADD(_tag, SAA5052, _clock) \
MCFG_DEVICE_CONFIG(_config)
#define SAA5050_INTERFACE(name) \
const saa5050_interface (name) =
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> saa5050_interface
struct saa5050_interface
{
const char *screen;
int gfxnum;
int x, y, size;
int rev;
devcb_read8 m_in_d_cb;
int m_cols;
int m_rows;
int m_size;
};
class saa5050_device : public device_t
// ======================> saa5050_device
class saa5050_device : public device_t,
public saa5050_interface
{
public:
saa5050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~saa5050_device() { global_free(m_token); }
// construction/destruction
saa5050_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant);
saa5050_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// optional information overrides
virtual const rom_entry *device_rom_region() const;
DECLARE_WRITE_LINE_MEMBER( dew_w );
DECLARE_WRITE_LINE_MEMBER( lose_w );
void write(UINT8 data);
DECLARE_WRITE_LINE_MEMBER( f1_w );
DECLARE_WRITE_LINE_MEMBER( tr6_w );
int get_rgb();
// NOTE: the following are provided for convenience only, SAA5050 is not a display controller
// this emulates the common setup where bit 7 of data inverts the display, and the
// bottom half of a double height row gets the same character data as the top half
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
enum
{
TYPE_5050,
TYPE_5052
};
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
virtual void device_start();
private:
// internal state
void *m_token;
void process_control_character(UINT8 data);
void get_character_data(UINT8 data);
devcb_resolved_read8 m_in_d_func;
const UINT8 *m_char_rom;
UINT8 m_code;
UINT8 m_last_code;
UINT8 m_char_data;
int m_bit;
rgb_t m_color;
int m_ra;
int m_bg;
int m_fg;
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_bottom_row;
bool m_hold;
int m_frame_count;
int m_variant;
};
// ======================> saa5052_device
class saa5052_device : public saa5050_device
{
public:
// construction/destruction
saa5052_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
// device type definition
extern const device_type SAA5050;
extern const device_type SAA5052;
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
#define MCFG_SAA5050_ADD(_tag, _interface) \
MCFG_DEVICE_ADD(_tag, SAA5050, 0) \
MCFG_DEVICE_CONFIG(_interface)
/***************************************************************************
DEVICE I/O FUNCTIONS
***************************************************************************/
void saa5050_update(device_t *device, bitmap_ind16 &bitmap, const rectangle &cliprect);
void saa5050_frame_advance(device_t *device);
GFXDECODE_EXTERN( saa5050 );
PALETTE_INIT( saa5050 );
WRITE8_DEVICE_HANDLER( saa5050_videoram_w );
READ8_DEVICE_HANDLER( saa5050_videoram_r );
#endif /* __SAA5050_H__ */
#endif

View File

@ -110,7 +110,7 @@ static ADDRESS_MAP_START( malzak_map, AS_PROGRAM, 8, malzak_state )
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE_LEGACY("s2636_1", s2636_work_ram_r, s2636_work_ram_w)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_RAM_WRITE(malzak_playfield_w)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_RAM
AM_RANGE(0x1800, 0x1fff) AM_MIRROR(0x6000) AM_DEVREADWRITE_LEGACY("saa5050", saa5050_videoram_r, saa5050_videoram_w)
AM_RANGE(0x1800, 0x1fff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("videoram")
AM_RANGE(0x2000, 0x2fff) AM_ROM
AM_RANGE(0x4000, 0x4fff) AM_ROM
AM_RANGE(0x6000, 0x6fff) AM_ROM
@ -131,7 +131,7 @@ static ADDRESS_MAP_START( malzak2_map, AS_PROGRAM, 8, malzak_state )
AM_RANGE(0x1500, 0x15ff) AM_MIRROR(0x6000) AM_DEVREADWRITE_LEGACY("s2636_1", s2636_work_ram_r, s2636_work_ram_w)
AM_RANGE(0x1600, 0x16ff) AM_MIRROR(0x6000) AM_RAM_WRITE(malzak_playfield_w)
AM_RANGE(0x1700, 0x17ff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("nvram")
AM_RANGE(0x1800, 0x1fff) AM_MIRROR(0x6000) AM_DEVREADWRITE_LEGACY("saa5050", saa5050_videoram_r, saa5050_videoram_w)
AM_RANGE(0x1800, 0x1fff) AM_MIRROR(0x6000) AM_RAM AM_SHARE("videoram")
AM_RANGE(0x2000, 0x2fff) AM_ROM
AM_RANGE(0x4000, 0x4fff) AM_ROM
AM_RANGE(0x6000, 0x6fff) AM_ROM
@ -256,48 +256,9 @@ static const gfx_layout charlayout =
// 8*8
};
static const gfx_layout saa5050_charlayout =
{
6, 10,
256,
1,
{ 0 },
{ 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8,
5*8, 6*8, 7*8, 8*8, 9*8 },
8 * 10
};
static const gfx_layout saa5050_hilayout =
{
6, 10,
256,
1,
{ 0 },
{ 2, 3, 4, 5, 6, 7 },
{ 0*8, 0*8, 1*8, 1*8, 2*8,
2*8, 3*8, 3*8, 4*8, 4*8 },
8 * 10
};
static const gfx_layout saa5050_lolayout =
{
6, 10,
256,
1,
{ 0 },
{ 2, 3, 4, 5, 6, 7 },
{ 5*8, 5*8, 6*8, 6*8, 7*8,
7*8, 8*8, 8*8, 9*8, 9*8 },
8 * 10
};
static GFXDECODE_START( malzak )
GFXDECODE_ENTRY( "gfx1", 0x0000, charlayout, 0, 16 )
GFXDECODE_ENTRY( "gfx2", 0x0000, saa5050_charlayout, 0, 128 )
GFXDECODE_ENTRY( "gfx2", 0x0000, saa5050_hilayout, 0, 128 )
GFXDECODE_ENTRY( "gfx2", 0x0000, saa5050_lolayout, 0, 128 )
GFXDECODE_END
@ -357,14 +318,16 @@ static const s2636_interface malzac_s2636_1_config =
"s2636snd_1"
};
static const saa5050_interface malzac_saa5050_intf =
READ8_MEMBER(malzak_state::videoram_r)
{
"screen",
1, /* starting gfxnum */
42, 24, 64, /* x, y, size */
1 /* rev y order */
};
return m_videoram[offset];
}
static SAA5050_INTERFACE( malzac_saa5050_intf )
{
DEVCB_DRIVER_MEMBER(malzak_state, videoram_r),
42, 24, 64 /* x, y, size */
};
void malzak_state::machine_start()
{
@ -400,7 +363,7 @@ static MACHINE_CONFIG_START( malzak, malzak_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
//MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(SAA5050_VBLANK))
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(480, 512) /* vert size is a guess */
MCFG_SCREEN_VISIBLE_AREA(0, 479, 0, 479)
MCFG_SCREEN_UPDATE_STATIC(malzak)
@ -411,7 +374,7 @@ static MACHINE_CONFIG_START( malzak, malzak_state )
MCFG_S2636_ADD("s2636_0", malzac_s2636_0_config)
MCFG_S2636_ADD("s2636_1", malzac_s2636_1_config)
MCFG_SAA5050_ADD("saa5050", malzac_saa5050_intf)
MCFG_SAA5050_ADD("saa5050", 6000000, malzac_saa5050_intf)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -454,10 +417,6 @@ ROM_START( malzak )
ROM_REGION( 0x0800, "gfx1", 0 )
ROM_LOAD( "malzak.1", 0x0000, 0x0800, CRC(74d5ff7b) SHA1(cae326370dc83b86542f9d070e2dc91b1b833356) )
ROM_REGION(0x01000, "gfx2",0) // SAA5050 internal character ROM
ROM_LOAD("p2000.chr", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc) )
ROM_END
ROM_START( malzak2 )
@ -478,10 +437,6 @@ ROM_START( malzak2 )
ROM_REGION( 0x0800, "gfx1", 0 )
ROM_LOAD( "malzak.1", 0x0000, 0x0800, CRC(74d5ff7b) SHA1(cae326370dc83b86542f9d070e2dc91b1b833356) )
ROM_REGION(0x01000, "gfx2",0) // SAA5050 internal character ROM
ROM_LOAD("p2000.chr", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc) )
ROM_END

View File

@ -4,12 +4,19 @@
*************************************************************************/
#include "video/saa5050.h"
class malzak_state : public driver_device
{
public:
malzak_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
: driver_device(mconfig, type, tag),
m_trom(*this, "saa5050"),
m_videoram(*this, "videoram")
{ }
required_device<saa5050_device> m_trom;
required_shared_ptr<UINT8> m_videoram;
/* misc */
// int playfield_x[256];
@ -31,6 +38,7 @@ public:
DECLARE_WRITE8_MEMBER(portc0_w);
DECLARE_READ8_MEMBER(collision_r);
DECLARE_WRITE8_MEMBER(malzak_playfield_w);
DECLARE_READ8_MEMBER(videoram_r);
virtual void machine_start();
virtual void machine_reset();
virtual void palette_init();
@ -40,4 +48,4 @@ public:
/*----------- defined in video/malzak.c -----------*/
SCREEN_UPDATE_IND16( malzak );
SCREEN_UPDATE_RGB32( malzak );

View File

@ -17,17 +17,16 @@
#include "video/saa5050.h"
#include "includes/malzak.h"
SCREEN_UPDATE_IND16( malzak )
SCREEN_UPDATE_RGB32( malzak )
{
const rgb_t *palette = palette_entry_list_raw(bitmap.palette());
malzak_state *state = screen.machine().driver_data<malzak_state>();
int sx, sy;
int x,y;
bitmap.fill(0);
bitmap.fill(RGB_BLACK);
saa5050_update(state->m_saa5050, bitmap, cliprect);
saa5050_frame_advance(state->m_saa5050);
state->m_trom->screen_update(screen, bitmap, cliprect);
// playfield - not sure exactly how this works...
for (x = 0; x < 16; x++)
@ -41,7 +40,7 @@ SCREEN_UPDATE_IND16( malzak )
if (sx < -15*2)
sx += 256*2;
drawgfxzoom_transpen(bitmap,cliprect, screen.machine().gfx[0], state->m_playfield_code[x * 16 + y], 7*2, 0, 0, sx, sy, 0x20000, 0x20000, 0);
drawgfxzoom_transpen(bitmap,cliprect, screen.machine().gfx[0], state->m_playfield_code[x * 16 + y], 2, 0, 0, sx, sy, 0x20000, 0x20000, 0);
}
/* update the S2636 chips */
@ -62,17 +61,17 @@ SCREEN_UPDATE_IND16( malzak )
int pixel1 = s2636_1_bitmap.pix16(y, x);
if (S2636_IS_PIXEL_DRAWN(pixel0)) {
bitmap.pix16(y*2, x*2) = S2636_PIXEL_COLOR(pixel0);
bitmap.pix16(y*2+1, x*2) = S2636_PIXEL_COLOR(pixel0);
bitmap.pix16(y*2, x*2+1) = S2636_PIXEL_COLOR(pixel0);
bitmap.pix16(y*2+1, x*2+1) = S2636_PIXEL_COLOR(pixel0);
bitmap.pix32(y*2, x*2) = palette[S2636_PIXEL_COLOR(pixel0)];
bitmap.pix32(y*2+1, x*2) = palette[S2636_PIXEL_COLOR(pixel0)];
bitmap.pix32(y*2, x*2+1) = palette[S2636_PIXEL_COLOR(pixel0)];
bitmap.pix32(y*2+1, x*2+1) = palette[S2636_PIXEL_COLOR(pixel0)];
}
if (S2636_IS_PIXEL_DRAWN(pixel1)) {
bitmap.pix16(y*2, x*2) = S2636_PIXEL_COLOR(pixel1);
bitmap.pix16(y*2+1, x*2) = S2636_PIXEL_COLOR(pixel1);
bitmap.pix16(y*2, x*2+1) = S2636_PIXEL_COLOR(pixel1);
bitmap.pix16(y*2+1, x*2+1) = S2636_PIXEL_COLOR(pixel1);
bitmap.pix32(y*2, x*2) = palette[S2636_PIXEL_COLOR(pixel1)];
bitmap.pix32(y*2+1, x*2) = palette[S2636_PIXEL_COLOR(pixel1)];
bitmap.pix32(y*2, x*2+1) = palette[S2636_PIXEL_COLOR(pixel1)];
bitmap.pix32(y*2+1, x*2+1) = palette[S2636_PIXEL_COLOR(pixel1)];
}
}
}

View File

@ -22,13 +22,16 @@ class a6809_state : public driver_device
public:
a6809_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_via(*this, "via")
m_via(*this, "via"),
m_videoram(*this, "videoram")
{ }
required_device<via6522_device> m_via;
required_shared_ptr<UINT8> m_videoram;
DECLARE_READ8_MEMBER( via_pb_r );
DECLARE_WRITE8_MEMBER( kb_w );
DECLARE_READ8_MEMBER( videoram_r );
UINT8 m_keydata;
virtual void machine_reset();
@ -38,7 +41,7 @@ public:
static ADDRESS_MAP_START(a6809_mem, AS_PROGRAM, 8, a6809_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000,0x03ff) AM_RAM
AM_RANGE(0x0400,0x07ff) AM_DEVREADWRITE_LEGACY("saa5050", saa5050_videoram_r, saa5050_videoram_w)
AM_RANGE(0x0400,0x07ff) AM_RAM AM_SHARE("videoram")
AM_RANGE(0x0800,0x0800) AM_DEVWRITE("mc6845", mc6845_device, address_w)
AM_RANGE(0x0801,0x0801) AM_DEVREADWRITE("mc6845", mc6845_device, register_r, register_w)
AM_RANGE(0x0900,0x090f) AM_MIRROR(0xf0) AM_DEVREADWRITE("via", via6522_device, read, write)
@ -59,16 +62,6 @@ void a6809_state::machine_reset()
{
}
static SCREEN_UPDATE_IND16( a6809 )
{
device_t *saa5050 = screen.machine().device("saa5050");
saa5050_update(saa5050, bitmap, cliprect);
saa5050_frame_advance(saa5050);
return 0;
}
static MC6845_UPDATE_ROW( a6809_update_row )
{
}
@ -87,12 +80,15 @@ static const mc6845_interface a6809_crtc6845_interface =
NULL
};
static const saa5050_interface a6809_saa5050_intf =
READ8_MEMBER( a6809_state::videoram_r )
{
"screen",
0, /* starting gfxnum */
40, 25, 40, /* x, y, size */
0 /* rev y order */
return m_videoram[offset];
}
static SAA5050_INTERFACE( a6809_saa5050_intf )
{
DEVCB_DRIVER_MEMBER(a6809_state, videoram_r),
40, 25, 40 /* x, y, size */
};
READ8_MEMBER( a6809_state::via_pb_r )
@ -140,16 +136,12 @@ static MACHINE_CONFIG_START( a6809, a6809_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(SAA5050_VBLANK))
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(40 * 12, 24 * 20)
MCFG_SCREEN_VISIBLE_AREA(0, 40 * 12 - 1, 0, 24 * 20 - 1)
MCFG_SCREEN_UPDATE_STATIC(a6809)
MCFG_SCREEN_UPDATE_DEVICE("saa5050", saa5050_device, screen_update)
MCFG_GFXDECODE(saa5050)
MCFG_PALETTE_LENGTH(128)
MCFG_PALETTE_INIT(saa5050)
MCFG_SAA5050_ADD("saa5050", a6809_saa5050_intf)
MCFG_SAA5050_ADD("saa5050", 6000000, a6809_saa5050_intf)
MCFG_VIA6522_ADD("via", XTAL_4MHz / 4, via_intf)
@ -165,9 +157,6 @@ ROM_START( a6809 )
ROM_REGION( 0x100, "proms", 0 )
ROM_LOAD( "acorn6809.ic11", 0x0000, 0x0100, CRC(7908317d) SHA1(e0f1e5bd3a8598d3b62bc432dd1f3892ed7e66d8) ) // address decoder
ROM_REGION(0x01000, "gfx1",0)
ROM_LOAD( "p2000.chr", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc) ) // copied from p2000t.c
ROM_END
/* Driver */

View File

@ -418,7 +418,7 @@ static ADDRESS_MAP_START( abc800c_mem, AS_PROGRAM, 8, abc800c_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x3fff) AM_RAM AM_SHARE("video_ram")
AM_RANGE(0x4000, 0x7bff) AM_ROM
AM_RANGE(0x7c00, 0x7fff) AM_READWRITE(char_ram_r, char_ram_w)
AM_RANGE(0x7c00, 0x7fff) AM_RAM AM_SHARE("char_ram")
AM_RANGE(0x8000, 0xffff) AM_RAM
ADDRESS_MAP_END

View File

@ -26,7 +26,7 @@
#include "formats/uef_cas.h"
#include "formats/csw_cas.h"
#include "sound/sn76496.h"
#include "video/saa505x.h"
#include "video/saa5050.h"
#include "includes/bbc.h"
@ -772,9 +772,11 @@ static const floppy_interface bbc_floppy_interface =
NULL
};
static const saa505x_interface bbc_saa505x_intf =
static SAA5050_INTERFACE( trom_intf )
{
bbc_draw_RGB_in,
DEVCB_NULL,
40, 24, 40 // x, y, size
};
static const mc6854_interface adlc_intf =
@ -854,7 +856,7 @@ static MACHINE_CONFIG_START( bbca, bbc_state )
MCFG_PALETTE_LENGTH(16)
MCFG_PALETTE_INIT_OVERRIDE(bbc_state,bbc)
MCFG_SAA505X_VIDEO_ADD("saa505x", bbc_saa505x_intf)
MCFG_SAA5050_ADD("saa505x", XTAL_12MHz/2, trom_intf)
MCFG_MC6845_ADD("mc6845",MC6845,2000000, bbc_mc6845_intf)
@ -948,7 +950,7 @@ static MACHINE_CONFIG_START( bbcm, bbc_state )
MCFG_PALETTE_INIT_OVERRIDE(bbc_state,bbc)
MCFG_SCREEN_UPDATE_DEVICE("mc6845", mc6845_device, screen_update)
MCFG_SAA505X_VIDEO_ADD("saa505x", bbc_saa505x_intf)
MCFG_SAA5050_ADD("saa505x", XTAL_12MHz/2, trom_intf)
MCFG_MC6845_ADD("mc6845",MC6845,2000000, bbc_mc6845_intf)

View File

@ -47,7 +47,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( p2000t_mem, AS_PROGRAM, 8, p2000t_state )
AM_RANGE(0x0000, 0x0fff) AM_ROM
AM_RANGE(0x1000, 0x4fff) AM_ROM
AM_RANGE(0x5000, 0x57ff) AM_DEVREADWRITE_LEGACY("saa5050", saa5050_videoram_r, saa5050_videoram_w)
AM_RANGE(0x5000, 0x57ff) AM_RAM AM_SHARE("videoram")
AM_RANGE(0x5800, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xffff) AM_NOP
ADDRESS_MAP_END
@ -55,7 +55,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( p2000m_mem, AS_PROGRAM, 8, p2000t_state )
AM_RANGE(0x0000, 0x0fff) AM_ROM
AM_RANGE(0x1000, 0x4fff) AM_ROM
AM_RANGE(0x5000, 0x5fff) AM_RAM AM_SHARE("p_videoram")
AM_RANGE(0x5000, 0x5fff) AM_RAM AM_SHARE("videoram")
AM_RANGE(0x6000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xffff) AM_NOP
ADDRESS_MAP_END
@ -207,23 +207,15 @@ static INTERRUPT_GEN( p2000_interrupt )
device->machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE);
}
static SCREEN_UPDATE_IND16( p2000t )
READ8_MEMBER( p2000t_state::videoram_r )
{
device_t *saa5050 = screen.machine().device("saa5050");
saa5050_update(saa5050, bitmap, cliprect);
saa5050_frame_advance(saa5050);
return 0;
return m_videoram[offset];
}
static const saa5050_interface p2000t_saa5050_intf =
static SAA5050_INTERFACE( p2000t_saa5050_intf )
{
"screen",
0, /* starting gfxnum */
40, 24 - 1, 80, /* x, y, size */
0 /* rev y order */
DEVCB_DRIVER_MEMBER(p2000t_state, videoram_r),
40, 24 - 1, 80 /* x, y, size */
};
/* Machine definition */
@ -237,15 +229,12 @@ static MACHINE_CONFIG_START( p2000t, p2000t_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(SAA5050_VBLANK))
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(40 * 12, 24 * 20)
MCFG_SCREEN_VISIBLE_AREA(0, 40 * 12 - 1, 0, 24 * 20 - 1)
MCFG_SCREEN_UPDATE_STATIC(p2000t)
MCFG_GFXDECODE(saa5050)
MCFG_PALETTE_LENGTH(128)
MCFG_PALETTE_INIT(saa5050)
MCFG_SCREEN_UPDATE_DEVICE("saa5050", saa5050_device, screen_update)
MCFG_SAA5050_ADD("saa5050", p2000t_saa5050_intf)
MCFG_SAA5050_ADD("saa5050", 6000000, p2000t_saa5050_intf)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -286,14 +275,13 @@ ROM_START(p2000t)
ROM_REGION(0x10000, "maincpu",0)
ROM_LOAD("p2000.rom", 0x0000, 0x1000, CRC(650784a3) SHA1(4dbb28adad30587f2ea536ba116898d459faccac))
ROM_LOAD("basic.rom", 0x1000, 0x4000, CRC(9d9d38f9) SHA1(fb5100436c99634a2592a10dff867f85bcff7aec))
ROM_REGION(0x01000, "gfx1",0)
ROM_LOAD("p2000.chr", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc))
ROM_END
ROM_START(p2000m)
ROM_REGION(0x10000, "maincpu",0)
ROM_LOAD("p2000.rom", 0x0000, 0x1000, CRC(650784a3) SHA1(4dbb28adad30587f2ea536ba116898d459faccac))
ROM_LOAD("basic.rom", 0x1000, 0x4000, CRC(9d9d38f9) SHA1(fb5100436c99634a2592a10dff867f85bcff7aec))
ROM_REGION(0x01000, "gfx1",0)
ROM_LOAD("p2000.chr", 0x0140, 0x08c0, BAD_DUMP CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc))
ROM_END

View File

@ -39,17 +39,20 @@ class poly_state : public driver_device
public:
poly_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_pia0(*this, "pia0"),
m_pia1(*this, "pia1")
m_maincpu(*this, "maincpu"),
m_pia0(*this, "pia0"),
m_pia1(*this, "pia1"),
m_videoram(*this, "videoram")
{ }
required_device<cpu_device> m_maincpu;
required_device<pia6821_device> m_pia0;
required_device<pia6821_device> m_pia1;
required_shared_ptr<UINT8> m_videoram;
DECLARE_WRITE8_MEMBER(kbd_put);
DECLARE_READ8_MEMBER(pia1_b_in);
DECLARE_READ_LINE_MEMBER(pia1_cb1_in);
DECLARE_READ8_MEMBER(videoram_r);
UINT8 m_term_data;
bool m_term_key;
virtual void machine_reset();
@ -70,7 +73,7 @@ static ADDRESS_MAP_START(poly_mem, AS_PROGRAM, 8, poly_state)
AM_RANGE(0xe050,0xe05f) AM_RAM //Dynamic Address Translater (arranges memory banks)
// AM_RANGE(0xe060,0xe060) Select Map 1
// AM_RANGE(0xe070,0xe070) Select Map 2
AM_RANGE(0xe800,0xebbf) AM_DEVREADWRITE_LEGACY("saa5050", saa5050_videoram_r, saa5050_videoram_w)
AM_RANGE(0xe800,0xebbf) AM_RAM AM_SHARE("videoram")
AM_RANGE(0xebc0,0xebff) AM_RAM
AM_RANGE(0xec00,0xefbf) AM_RAM // screen 2 AM_DEVREADWRITE_LEGACY("saa5050", saa5050_videoram_r, saa5050_videoram_w)
AM_RANGE(0xefc0,0xefff) AM_RAM
@ -142,23 +145,15 @@ static const ptm6840_interface poly_ptm_intf =
DEVCB_NULL
};
static SCREEN_UPDATE_IND16( poly )
READ8_MEMBER( poly_state::videoram_r )
{
device_t *saa5050 = screen.machine().device("saa5050");
saa5050_update(saa5050, bitmap, cliprect);
saa5050_frame_advance(saa5050);
return 0;
return m_videoram[offset];
}
static const saa5050_interface poly_saa5050_intf =
static SAA5050_INTERFACE( poly_saa5050_intf )
{
"screen",
0, /* starting gfxnum */
40, 24, 40, /* x, y, size */
0 /* rev y order */
DEVCB_DRIVER_MEMBER(poly_state, videoram_r),
40, 24, 40 /* x, y, size */
};
// temporary hack
@ -185,16 +180,13 @@ static MACHINE_CONFIG_START( poly, poly_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(50)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(SAA5050_VBLANK))
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(40 * 12, 24 * 20)
MCFG_SCREEN_VISIBLE_AREA(0, 40 * 12 - 1, 0, 24 * 20 - 1)
MCFG_SCREEN_UPDATE_STATIC(poly)
MCFG_GFXDECODE(saa5050)
MCFG_PALETTE_LENGTH(128)
MCFG_PALETTE_INIT(saa5050)
MCFG_SCREEN_UPDATE_DEVICE("saa5050", saa5050_device, screen_update)
/* Devices */
MCFG_SAA5050_ADD("saa5050", poly_saa5050_intf)
MCFG_SAA5050_ADD("saa5050", 6000000, poly_saa5050_intf)
MCFG_PIA6821_ADD( "pia0", poly_pia0_intf )
MCFG_PIA6821_ADD( "pia1", poly_pia1_intf )
MCFG_PTM6840_ADD("ptm", poly_ptm_intf)
@ -222,10 +214,6 @@ ROM_START( poly1 )
ROMX_LOAD( "v2bas3.bin", 0xc000, 0x1000, CRC(04a58be5) SHA1(729fa02c76783213e40bb179e60c09d4b439ab90), ROM_BIOS(2) )
ROMX_LOAD( "v2bas4.bin", 0x9000, 0x1000, CRC(328fe790) SHA1(43dca92092b27627603d3588f91cf9eca24ed29f), ROM_BIOS(2) )
ROMX_LOAD( "slrt14_00f9.bin", 0xf000, 0x1000, CRC(6559a2ce) SHA1(7c38f449ca122342732123b56992ed0c446406c2), ROM_BIOS(2) )
/* This is SAA5050 came with poly emulator, identical to p2000t */
ROM_REGION(0x01000, "gfx1",0)
ROM_LOAD("p2000.chr", 0x0140, 0x08c0, CRC(78c17e3e) SHA1(4e1c59dc484505de1dc0b1ba7e5f70a54b0d4ccc))
ROM_END
/* Driver */

View File

@ -187,18 +187,16 @@ public:
m_trom(*this, SAA5052_TAG)
{ }
required_device<saa5050_device> m_trom;
required_device<saa5052_device> m_trom;
DECLARE_DRIVER_INIT(driver_init);
virtual void video_start();
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
offs_t translate_trom_offset(offs_t offset);
void hr_update(bitmap_ind16 &bitmap, const rectangle &cliprect);
void hr_update(bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_READ8_MEMBER( char_ram_r );
DECLARE_WRITE8_MEMBER( char_ram_w );
DECLARE_DIRECT_UPDATE_MEMBER( direct_update_handler );
};

View File

@ -17,6 +17,7 @@
#include "machine/wd17xx.h"
#include "machine/upd7002.h"
#include "video/mc6845.h"
#include "video/saa5050.h"
#include "sound/sn76496.h"
class bbc_state : public driver_device
@ -26,6 +27,7 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_sn(*this, "sn76489"),
m_trom(*this, "saa505x"),
m_ACCCON_IRR(CLEAR_LINE),
m_via_system_irq(CLEAR_LINE),
m_via_user_irq(CLEAR_LINE),
@ -34,6 +36,7 @@ public:
required_device<cpu_device> m_maincpu;
optional_device<sn76489_new_device> m_sn;
required_device<saa5050_device> m_trom;
void check_interrupts();
@ -193,7 +196,6 @@ public:
unsigned char m_pixel_bits[256];
int m_BBC_HSync;
int m_BBC_VSync;
device_t *m_saa505x;
@ -336,7 +338,6 @@ extern const uPD7002_interface bbc_uPD7002;
SCREEN_UPDATE_IND16( bbc );
void bbc_draw_RGB_in(device_t *device, int offset, int data);
void bbc_set_video_memory_lookups(running_machine &machine, int ramsize);
void bbc_setscreenstart(running_machine &machine, int b4, int b5);
void bbcbp_setvideoshadow(running_machine &machine, int vdusel);

View File

@ -18,9 +18,10 @@ class p2000t_state : public driver_device
public:
p2000t_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_speaker(*this, SPEAKER_TAG),
m_p_videoram(*this, "p_videoram"){ }
m_maincpu(*this, "maincpu"),
m_speaker(*this, SPEAKER_TAG),
m_videoram(*this, "videoram")
{ }
required_device<cpu_device> m_maincpu;
required_device<device_t> m_speaker;
@ -33,7 +34,8 @@ public:
DECLARE_WRITE8_MEMBER(p2000t_port_888b_w);
DECLARE_WRITE8_MEMBER(p2000t_port_8c90_w);
DECLARE_WRITE8_MEMBER(p2000t_port_9494_w);
optional_shared_ptr<UINT8> m_p_videoram;
DECLARE_READ8_MEMBER(videoram_r);
required_shared_ptr<UINT8> m_videoram;
UINT8 m_port_101f;
UINT8 m_port_202f;
UINT8 m_port_303f;

View File

@ -543,7 +543,6 @@ $(MESSOBJ)/shared.a: \
$(MESS_VIDEO)/hd44780.o \
$(MESS_VIDEO)/hd66421.o \
$(MESS_VIDEO)/mc6847.o \
$(MESS_VIDEO)/saa505x.o \
$(MESS_VIDEO)/tms3556.o \
$(MESS_VIDEO)/upd7220.o \
$(MESS_MACHINE)/applefdc.o \

View File

@ -14,6 +14,19 @@
#define VERTICAL_PORCH_HACK 29
static const rgb_t PALETTE[] =
{
RGB_BLACK,
MAKE_RGB(0xff, 0x00, 0x00), // red
MAKE_RGB(0x00, 0xff, 0x00), // green
MAKE_RGB(0xff, 0xff, 0x00), // yellow
MAKE_RGB(0x00, 0x00, 0xff), // blue
MAKE_RGB(0xff, 0x00, 0xff), // magenta
MAKE_RGB(0x00, 0xff, 0xff), // cyan
RGB_WHITE
};
//**************************************************************************
// HIGH RESOLUTION GRAPHICS
@ -50,33 +63,15 @@ WRITE8_MEMBER( abc800_state::hrc_w )
offs_t abc800c_state::translate_trom_offset(offs_t offset)
{
int row = offset >> 7;
int col = offset & 0x7f;
int row = offset / 40;
int col = offset % 40;
if (col >= 80) row += 16;
else if (col >= 40) row += 8;
offset = ((row & 0x07) * 0x80) + col;
return (row * 40) + (col % 40);
}
if (row & 0x08) offset += 0x28;
if (row & 0x10) offset += 0x50;
//-------------------------------------------------
// char_ram_r - character RAM read
//-------------------------------------------------
READ8_MEMBER( abc800c_state::char_ram_r )
{
return saa5050_videoram_r(m_trom, translate_trom_offset(offset));
}
//-------------------------------------------------
// char_ram_w - character RAM write
//-------------------------------------------------
WRITE8_MEMBER( abc800c_state::char_ram_w )
{
saa5050_videoram_w(m_trom, translate_trom_offset(offset), data);
return offset;
}
@ -84,7 +79,7 @@ WRITE8_MEMBER( abc800c_state::char_ram_w )
// hr_update - high resolution screen update
//-------------------------------------------------
void abc800c_state::hr_update(bitmap_ind16 &bitmap, const rectangle &cliprect)
void abc800c_state::hr_update(bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
UINT16 addr = 0;
@ -104,19 +99,16 @@ void abc800c_state::hr_update(bitmap_ind16 &bitmap, const rectangle &cliprect)
if (color)
{
rgb_t rgb = palette_entry_get_color(machine().palette, bitmap.pix16(y, x));
bool black = !RGB_RED(rgb) && !RGB_GREEN(rgb) && !RGB_BLUE(rgb);
bool black = bitmap.pix32(y, x) == RGB_BLACK;
bool opaque = !BIT(fgctl, 3);
if (black || opaque)
{
color += 128;
bitmap.pix32(y, x) = PALETTE[color];
bitmap.pix32(y, x + 1) = PALETTE[color];
bitmap.pix16(y, x) = color;
bitmap.pix16(y, x + 1) = color;
bitmap.pix16(y + 1, x) = color;
bitmap.pix16(y + 1, x + 1) = color;
bitmap.pix32(y + 1, x) = PALETTE[color];
bitmap.pix32(y + 1, x + 1) = PALETTE[color];
}
}
@ -144,43 +136,21 @@ void abc800_state::video_start()
}
//-------------------------------------------------
// VIDEO_START( abc800c )
//-------------------------------------------------
void abc800c_state::video_start()
{
abc800_state::video_start();
// initialize palette
palette_set_color_rgb(machine(), 128+0, 0x00, 0x00, 0x00); // black
palette_set_color_rgb(machine(), 128+1, 0xff, 0x00, 0x00); // red
palette_set_color_rgb(machine(), 128+2, 0x00, 0xff, 0x00); // green
palette_set_color_rgb(machine(), 128+3, 0xff, 0xff, 0x00); // yellow
palette_set_color_rgb(machine(), 128+4, 0x00, 0x00, 0xff); // blue
palette_set_color_rgb(machine(), 128+5, 0xff, 0x00, 0xff); // magenta
palette_set_color_rgb(machine(), 128+6, 0x00, 0xff, 0xff); // cyan
palette_set_color_rgb(machine(), 128+7, 0xff, 0xff, 0xff); // white
}
//-------------------------------------------------
// SCREEN_UPDATE( abc800c )
//-------------------------------------------------
UINT32 abc800c_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
UINT32 abc800c_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
// clear screen
bitmap.fill(get_black_pen(machine()), cliprect);
bitmap.fill(RGB_BLACK, cliprect);
// draw text
if (!BIT(m_fgctl, 7))
{
saa5050_update(m_trom, bitmap, cliprect);
m_trom->screen_update(screen, bitmap, cliprect);
}
saa5050_frame_advance(m_trom);
// draw HR graphics
hr_update(bitmap, cliprect);
@ -189,15 +159,18 @@ UINT32 abc800c_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap,
//-------------------------------------------------
// saa5050_interface trom_intf
// SAA5050_INTERFACE( trom_intf )
//-------------------------------------------------
static const saa5050_interface trom_intf =
READ8_MEMBER( abc800c_state::char_ram_r )
{
SCREEN_TAG,
0, // starting gfxnum
40, 24, 40, // x, y, size
0 // rev y order
return m_char_ram[translate_trom_offset(offset)];
}
static SAA5050_INTERFACE( trom_intf )
{
DEVCB_DRIVER_MEMBER(abc800c_state, char_ram_r),
40, 24, 40 // x, y, size
};
@ -214,12 +187,7 @@ MACHINE_CONFIG_FRAGMENT( abc800c_video )
MCFG_SCREEN_SIZE(480, 480)
MCFG_SCREEN_VISIBLE_AREA(0, 480-1, 0, 480-1)
MCFG_PALETTE_LENGTH(128+8)
MCFG_PALETTE_INIT(saa5050)
MCFG_GFXDECODE(saa5050)
MCFG_SAA5050_ADD(SAA5052_TAG, trom_intf)
MCFG_SAA5052_ADD(SAA5052_TAG, XTAL_12MHz/2, trom_intf)
MACHINE_CONFIG_END

View File

@ -18,7 +18,7 @@
#include "emu.h"
#include "includes/bbc.h"
#include "saa505x.h"
#include "video/saa5050.h"
#include "video/mc6845.h"
/************************************************************************
@ -191,7 +191,6 @@ int returned_pixels[6];
static MC6845_UPDATE_ROW( vid_update_row )
{
bbc_state *state = device->machine().driver_data<bbc_state>();
const rgb_t *palette = palette_entry_list_raw(bitmap.palette());
@ -199,9 +198,8 @@ static MC6845_UPDATE_ROW( vid_update_row )
if (state->m_videoULA_teletext_normal_select)
{
teletext_LOSE_w(state->m_saa505x, 0,0);
teletext_LOSE_w(state->m_saa505x, 0,1);
state->m_trom->lose_w(1);
state->m_trom->lose_w(0);
for(int x_pos=0; x_pos<x_count; x_pos++)
{
@ -211,25 +209,38 @@ static MC6845_UPDATE_ROW( vid_update_row )
returned_pixel_count=0;
state->m_trom->write((state->m_Teletext_Latch&0x3f)|(state->m_Teletext_Latch&0x40));
teletext_F1(state->m_saa505x);
teletext_data_w(state->m_saa505x, 0, (state->m_Teletext_Latch&0x3f)|(state->m_Teletext_Latch&0x40));
state->m_trom->f1_w(1);
state->m_trom->f1_w(0);
if (((ma>>13)&1)==0)
{
state->m_Teletext_Latch=0;
} else {
state->m_Teletext_Latch=(state->m_BBC_Video_RAM[calculate_video_address(state,ma+x_pos,ra)]&0x7f);
state->m_Teletext_Latch=(state->m_BBC_Video_RAM[calculate_video_address(state,ma+x_pos,ra)]);
}
for(int pixelno=0;pixelno<6;pixelno++)
{
int col=returned_pixels[pixelno];
state->m_trom->tr6_w(1);
state->m_trom->tr6_w(0);
bitmap.pix32(y, (x_pos*state->m_pixels_per_byte)+pixelno)=palette[col];
int col=state->m_trom->get_rgb();
int r = BIT(col, 0) * 0xff;
int g = BIT(col, 1) * 0xff;
int b = BIT(col, 2) * 0xff;
rgb_t rgb = MAKE_RGB(r, g, b);
bitmap.pix32(y, (x_pos*state->m_pixels_per_byte)+pixelno) = rgb;
}
}
if (ra == 18)
{
state->m_trom->lose_w(1);
state->m_trom->lose_w(0);
}
}
else
@ -268,7 +279,7 @@ static MC6845_UPDATE_ROW( vid_update_row )
static WRITE_LINE_DEVICE_HANDLER( bbc_vsync )
{
bbc_state *bstate = device->machine().driver_data<bbc_state>();
teletext_DEW(bstate->m_saa505x);
bstate->m_trom->dew_w(state);
}
@ -287,14 +298,6 @@ const mc6845_interface bbc_mc6845_intf =
};
void bbc_draw_RGB_in(device_t *device, int offset,int data)
{
if (returned_pixel_count<6)
returned_pixels[returned_pixel_count++]=7-data;
}
/************************************************************************
@ -360,7 +363,6 @@ static void common_init(running_machine &machine, int memorySize)
state->m_VideoULA_CR_counter = 0;
set_pixel_lookup(state);
state->m_saa505x = machine.device("saa505x");
state->m_BBC_Video_RAM = state->memregion("maincpu")->base();
state->m_memorySize=memorySize;

View File

@ -20,7 +20,7 @@ VIDEO_START_MEMBER(p2000t_state,p2000m)
SCREEN_UPDATE_IND16( p2000m )
{
p2000t_state *state = screen.machine().driver_data<p2000t_state>();
UINT8 *videoram = state->m_p_videoram;
UINT8 *videoram = state->m_videoram;
int offs, sx, sy, code, loop;
for (offs = 0; offs < 80 * 24; offs++)

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +0,0 @@
/************************************************************************
saa505x
MESS Driver By:
Gordon Jefferyes
mess_bbc@gjeffery.dircon.co.uk
************************************************************************/
typedef struct _saa505x_interface saa505x_interface;
struct _saa505x_interface
{
void (*out_Pixel_func)(device_t *device, int offset, int data);
};
void teletext_DEW(device_t *device);
void teletext_LOSE_w(device_t *device, int offset, int data);
void teletext_data_w(device_t *device, int offset, int data);
void teletext_F1(device_t *device);
class saa505x_device : public device_t
{
public:
saa505x_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
~saa505x_device() { global_free(m_token); }
// access to legacy token
void *token() const { assert(m_token != NULL); return m_token; }
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
private:
// internal state
void *m_token;
};
extern const device_type SAA505X;
#define MCFG_SAA505X_VIDEO_ADD(_tag, _intf) \
MCFG_DEVICE_ADD(_tag, SAA505X, 0) \
MCFG_DEVICE_CONFIG(_intf)