Sync with MESS (nw)
This commit is contained in:
parent
857f3e767b
commit
695fef3595
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1388,6 +1388,8 @@ src/emu/video/huc6202.c svneol=native#text/plain
|
||||
src/emu/video/huc6202.h svneol=native#text/plain
|
||||
src/emu/video/huc6260.c svneol=native#text/plain
|
||||
src/emu/video/huc6260.h svneol=native#text/plain
|
||||
src/emu/video/huc6261.c svneol=native#text/plain
|
||||
src/emu/video/huc6261.h svneol=native#text/plain
|
||||
src/emu/video/huc6270.c svneol=native#text/plain
|
||||
src/emu/video/huc6270.h svneol=native#text/plain
|
||||
src/emu/video/i8275.c svneol=native#text/plain
|
||||
|
@ -287,6 +287,7 @@ EMUVIDEOOBJS = \
|
||||
$(EMUVIDEO)/hd63484.o \
|
||||
$(EMUVIDEO)/huc6202.o \
|
||||
$(EMUVIDEO)/huc6260.o \
|
||||
$(EMUVIDEO)/huc6261.o \
|
||||
$(EMUVIDEO)/huc6270.o \
|
||||
$(EMUVIDEO)/i8275.o \
|
||||
$(EMUVIDEO)/k053250.o \
|
||||
|
409
src/emu/video/huc6261.c
Normal file
409
src/emu/video/huc6261.c
Normal file
@ -0,0 +1,409 @@
|
||||
/**********************************************************************
|
||||
|
||||
Hudson/NEC HuC6261 Video Colour Encoder
|
||||
|
||||
The HuC6261 generates the tv control signals. A full line lasts
|
||||
1365 "master" cycles (typically at 21.47727Mhz).
|
||||
|
||||
HSync is low for 237 and high for 1128 master cycles.
|
||||
VSync is low for 4095 master cycles (3 lines).
|
||||
VSync changes 30 master cycles after HSync would go low.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "profiler.h"
|
||||
#include "huc6261.h"
|
||||
|
||||
#define LOG 0
|
||||
|
||||
#define HUC6261_HSYNC_LENGTH 237
|
||||
#define HUC6261_HSYNC_START ( HUC6261_WPF - HUC6261_HSYNC_LENGTH )
|
||||
|
||||
|
||||
const device_type HUC6261 = &device_creator<huc6261_device>;
|
||||
|
||||
|
||||
void huc6261_device::device_config_complete()
|
||||
{
|
||||
const huc6261_interface *intf = reinterpret_cast<const huc6261_interface *>(static_config());
|
||||
|
||||
if ( intf != NULL )
|
||||
{
|
||||
*static_cast<huc6261_interface *>(this) = *intf;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
huc6261_device::huc6261_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, HUC6261, "HuC6261", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void huc6261_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
int vpos = m_screen->vpos();
|
||||
int hpos = m_screen->hpos();
|
||||
int h = m_last_h;
|
||||
int v = m_last_v;
|
||||
UINT32 *bitmap_line = &m_bmp->pix32(v);
|
||||
|
||||
while ( h != hpos || v != vpos )
|
||||
{
|
||||
if ( m_pixel_clock == 0 )
|
||||
{
|
||||
g_profiler.start( PROFILER_VIDEO );
|
||||
/* Get next pixel information */
|
||||
m_pixel_data = 0; //m_get_next_pixel_data( 0, 0xffff );
|
||||
g_profiler.stop();
|
||||
}
|
||||
|
||||
bitmap_line[ h ] = m_palette[ m_pixel_data ];
|
||||
m_pixel_clock = ( m_pixel_clock + 1 ) % m_pixels_per_clock;
|
||||
h = ( h + 1 ) % HUC6261_WPF;
|
||||
|
||||
switch( h )
|
||||
{
|
||||
case HUC6261_HSYNC_START: /* Start of HSync */
|
||||
m_huc6270_a->hsync_changed( 0 );
|
||||
m_huc6270_b->hsync_changed( 0 );
|
||||
// if ( v == 0 )
|
||||
// {
|
||||
// /* Check if the screen should be resized */
|
||||
// m_height = HUC6261_LPF - ( m_blur ? 1 : 0 );
|
||||
// if ( m_height != video_screen_get_height( m_screen ) )
|
||||
// {
|
||||
// rectangle visible_area;
|
||||
//
|
||||
// /* TODO: Set proper visible area parameters */
|
||||
// visible_area.min_x = 64;
|
||||
// visible_area.min_y = 18;
|
||||
// visible_area.max_x = 64 + 1024 + 64 - 1;
|
||||
// visible_area.max_y = 18 + 242 - 1;
|
||||
//
|
||||
// video_screen_configure( m_screen, HUC6261_WPF, m_height, &visible_area, HZ_TO_ATTOSECONDS( device->clock / ( HUC6261_WPF * m_height ) ) );
|
||||
// }
|
||||
// }
|
||||
break;
|
||||
|
||||
case 0: /* End of HSync */
|
||||
m_huc6270_a->hsync_changed( 1 );
|
||||
m_huc6270_b->hsync_changed( 1 );
|
||||
m_pixel_clock = 0;
|
||||
v = ( v + 1 ) % m_height;
|
||||
bitmap_line = &m_bmp->pix32(v);
|
||||
break;
|
||||
|
||||
case HUC6261_HSYNC_START + 30: /* End/Start of VSync */
|
||||
if ( v>= m_height - 4 )
|
||||
{
|
||||
int vsync = ( v >= m_height - 4 && v < m_height - 1 ) ? 0 : 1;
|
||||
|
||||
m_huc6270_a->vsync_changed( vsync );
|
||||
m_huc6270_b->vsync_changed( vsync );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_last_h = h;
|
||||
m_last_v = v;
|
||||
|
||||
/* Reschedule timer */
|
||||
if ( m_last_h < HUC6261_HSYNC_START )
|
||||
{
|
||||
/* Next event is start of HSync signal */
|
||||
v = m_last_v;
|
||||
h = HUC6261_HSYNC_START;
|
||||
}
|
||||
else if ( ( m_last_v == m_height - 4 || m_last_v == m_height - 1 ) && m_last_h < HUC6261_HSYNC_START + 30 )
|
||||
{
|
||||
/* Next event is start/end of VSync signal */
|
||||
v = m_last_v;
|
||||
h = HUC6261_HSYNC_START + 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Next event is end of HSync signal */
|
||||
v = ( m_last_v + 1 ) % m_height;
|
||||
h = 0;
|
||||
}
|
||||
|
||||
/* Ask our slave device for time until next possible event */
|
||||
{
|
||||
UINT16 next_event_clocks = HUC6261_WPF; //m_get_time_til_next_event( 0, 0xffff );
|
||||
int event_hpos, event_vpos;
|
||||
|
||||
/* Adjust for pixel clocks per pixel */
|
||||
next_event_clocks *= m_pixels_per_clock;
|
||||
|
||||
/* Adjust for clocks left to go for current pixel */
|
||||
next_event_clocks += ( m_pixels_per_clock - ( m_pixel_clock + 1 ) );
|
||||
|
||||
event_hpos = hpos + next_event_clocks;
|
||||
event_vpos = vpos;
|
||||
while ( event_hpos > HUC6261_WPF )
|
||||
{
|
||||
event_vpos += 1;
|
||||
event_hpos -= HUC6261_WPF;
|
||||
}
|
||||
|
||||
if ( event_vpos < v || ( event_vpos == v && event_hpos <= h ) )
|
||||
{
|
||||
if ( event_vpos > vpos || ( event_vpos == vpos && event_hpos > hpos ) )
|
||||
{
|
||||
v = event_vpos;
|
||||
h = event_hpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_timer->adjust( m_screen->time_until_pos( v, h ) );
|
||||
}
|
||||
|
||||
|
||||
void huc6261_device::video_update( bitmap_rgb32 &bitmap, const rectangle &cliprect )
|
||||
{
|
||||
copybitmap( bitmap, *m_bmp, 0, 0, 0, 0, cliprect );
|
||||
}
|
||||
|
||||
|
||||
READ16_MEMBER( huc6261_device::read )
|
||||
{
|
||||
UINT16 data = 0xFFFF;
|
||||
|
||||
switch ( offset & 1 )
|
||||
{
|
||||
/* Status info */
|
||||
case 0x00:
|
||||
{
|
||||
UINT16 vpos = m_screen->vpos();
|
||||
UINT16 hpos = m_screen->hpos();
|
||||
|
||||
data = ( vpos << 5 ) | ( m_register & 0x1F);
|
||||
|
||||
if ( vpos >= 22 && vpos < 262 && hpos < HUC6261_HSYNC_START )
|
||||
{
|
||||
data |= 0x8000;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Register contents(?) */
|
||||
case 0x01:
|
||||
switch( m_register )
|
||||
{
|
||||
case 0x00:
|
||||
data = m_control;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
data = m_address;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
data = m_palette_latch;
|
||||
m_address = ( m_address + 1 ) & 0x1FF;
|
||||
m_palette_latch = m_palette[ m_address ];
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
data = m_priority[4] | ( m_priority[5] << 4 ) | ( m_priority[6] << 8 );
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
data = m_priority[0] | ( m_priority[1] << 4 ) | ( m_priority[2] << 8 ) | ( m_priority[3] << 12 );;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
WRITE16_MEMBER( huc6261_device::write )
|
||||
{
|
||||
switch ( offset & 1 )
|
||||
{
|
||||
/* Register */
|
||||
case 0x00:
|
||||
m_register = data;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
logerror("huc6261: writing 0x%04x to register 0x%02x\n", data, m_register );
|
||||
switch( m_register )
|
||||
{
|
||||
/* Control register */
|
||||
// -x-------------- Enable HuC6271: 0 - disabled, 1 - enabled
|
||||
// --x------------- Enable HuC6272 BG3: 0 - disabled, 1 - enabled
|
||||
// ---x------------ Enable HuC6272 BG2: 0 - disabled, 1 - enabled
|
||||
// ----x----------- Enable Huc6272 BG1: 0 - disabled, 1 - enabled
|
||||
// -----x---------- Enable HuC6272 BG0: 0 - disabled, 1 - enabled
|
||||
// ------x--------- Enable HuC6270 SPR: 0 - disabled, 1 - enabled
|
||||
// -------x-------- Enable HuC6270 BG: 0 - disabled, 1 - enabled
|
||||
// --------x------- Number of SPR colors?: 0 - 16, 1 - 256
|
||||
// ---------x------ Number of BG colors?: 0 - 16, 1 - 256
|
||||
// ------------x--- Dot clock: 0 - 5MHz, 1 - 7MHz
|
||||
// -------------x-- Synchronization: 0 - internal, 1 - external
|
||||
// --------------xx Screen height: 00 - 262 lines, 01 - 263 lines, 10 - interlace, 11 - unknown/undefined
|
||||
case 0x00:
|
||||
m_control = data;
|
||||
m_pixels_per_clock = ( data & 0x04 ) ? 3 : 4;
|
||||
break;
|
||||
|
||||
// Palette address
|
||||
case 0x01:
|
||||
m_address = data & 0x1FF;
|
||||
m_palette_latch = m_palette[ m_address ];
|
||||
break;
|
||||
|
||||
// Palette data
|
||||
case 0x02:
|
||||
m_palette_latch = data;
|
||||
m_palette[ m_address ] = m_palette_latch;
|
||||
m_address = ( m_address + 1 ) & 0x1FF;
|
||||
break;
|
||||
|
||||
// Palette offset 0
|
||||
case 0x04:
|
||||
break;
|
||||
|
||||
// Palette offset 1
|
||||
case 0x05:
|
||||
break;
|
||||
|
||||
// Palette offset 2
|
||||
case 0x06:
|
||||
break;
|
||||
|
||||
// Palette offset 3
|
||||
case 0x07:
|
||||
break;
|
||||
|
||||
// Priority 0
|
||||
// -----xxx-------- HuC6271 Rainbow priority
|
||||
// ---------xxx---- HuC6270 SPR priority
|
||||
// -------------xxx HuC6270 BG priority
|
||||
case 0x08:
|
||||
m_priority[4] = ( data >> 0 ) & 0x07;
|
||||
m_priority[5] = ( data >> 4 ) & 0x07;
|
||||
m_priority[6] = ( data >> 8 ) & 0x07;
|
||||
break;
|
||||
|
||||
// Priority 1
|
||||
// -xxx------------ HuC6272 BG3 priority
|
||||
// -----xxx-------- HuC6272 BG2 priority
|
||||
// ---------xxx---- HuC6272 BG1 priority
|
||||
// -------------xxx HuC6272 BG0 priority
|
||||
case 0x09:
|
||||
m_priority[0] = ( data >> 0 ) & 0x07;
|
||||
m_priority[1] = ( data >> 4 ) & 0x07;
|
||||
m_priority[2] = ( data >> 8 ) & 0x07;
|
||||
m_priority[3] = ( data >> 12 ) & 0x07;
|
||||
break;
|
||||
|
||||
// Chroma key Y
|
||||
case 0x0A:
|
||||
break;
|
||||
|
||||
// Chroma key U
|
||||
case 0x0B:
|
||||
break;
|
||||
|
||||
// Chroma key V
|
||||
case 0x0C:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x0D:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x0E:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x0F:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x10:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x11:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x12:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x13:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x14:
|
||||
break;
|
||||
|
||||
//
|
||||
case 0x15:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void huc6261_device::device_start()
|
||||
{
|
||||
/* Make sure we are supplied all our mandatory tags */
|
||||
assert( screen_tag != NULL );
|
||||
assert( huc6270_a_tag != NULL );
|
||||
assert( huc6270_b_tag != NULL );
|
||||
|
||||
m_timer = timer_alloc();
|
||||
m_screen = machine().device<screen_device>( screen_tag );
|
||||
m_huc6270_a = machine().device<huc6270_device>( huc6270_a_tag );
|
||||
m_huc6270_b = machine().device<huc6270_device>( huc6270_b_tag );
|
||||
|
||||
m_bmp = auto_bitmap_rgb32_alloc( machine(), HUC6261_WPF, HUC6261_LPF );
|
||||
|
||||
/* We want to have valid devices */
|
||||
assert( m_screen != NULL );
|
||||
assert( m_huc6270_a != NULL );
|
||||
assert( m_huc6270_b != NULL );
|
||||
|
||||
save_item(NAME(m_last_h));
|
||||
save_item(NAME(m_last_v));
|
||||
save_item(NAME(m_height));
|
||||
save_item(NAME(m_palette));
|
||||
save_item(NAME(m_palette_latch));
|
||||
save_item(NAME(m_address));
|
||||
save_item(NAME(m_register));
|
||||
save_item(NAME(m_control));
|
||||
save_item(NAME(m_priority));
|
||||
save_item(NAME(m_pixels_per_clock));
|
||||
save_item(NAME(m_pixel_data));
|
||||
save_item(NAME(m_pixel_clock));
|
||||
}
|
||||
|
||||
|
||||
void huc6261_device::device_reset()
|
||||
{
|
||||
m_register = 0;
|
||||
m_pixels_per_clock = 4;
|
||||
m_height = 263;
|
||||
|
||||
m_last_v = m_screen->vpos();
|
||||
m_last_h = m_screen->hpos();
|
||||
m_timer->adjust( m_screen->time_until_pos( ( m_screen->vpos() + 1 ) % 263, 0 ) );
|
||||
}
|
||||
|
83
src/emu/video/huc6261.h
Normal file
83
src/emu/video/huc6261.h
Normal file
@ -0,0 +1,83 @@
|
||||
/**********************************************************************
|
||||
|
||||
Hudson/NEC HuC6261 interface and definitions
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
#ifndef __HUC6261_H_
|
||||
#define __HUC6261_H_
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/devhelpr.h"
|
||||
#include "video/huc6270.h"
|
||||
|
||||
|
||||
/* Screen timing stuff */
|
||||
#define HUC6261_WPF 1365 /* width of a line in frame including blanking areas */
|
||||
#define HUC6261_LPF 263 /* max number of lines in a single frame */
|
||||
|
||||
|
||||
#define MCFG_HUC6261_ADD( _tag, clock, _intrf ) \
|
||||
MCFG_DEVICE_ADD( _tag, HUC6261, clock ) \
|
||||
MCFG_DEVICE_CONFIG( _intrf )
|
||||
|
||||
|
||||
typedef struct _huc6261_interface huc6261_interface;
|
||||
struct _huc6261_interface
|
||||
{
|
||||
/* Tag for the screen we will be drawing on */
|
||||
const char *screen_tag;
|
||||
|
||||
/* Tags for the 2 HuC6270 devices */
|
||||
const char *huc6270_a_tag;
|
||||
const char *huc6270_b_tag;
|
||||
};
|
||||
|
||||
|
||||
class huc6261_device : public device_t,
|
||||
public huc6261_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
huc6261_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
void video_update(bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_READ16_MEMBER( read );
|
||||
DECLARE_WRITE16_MEMBER( write );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_config_complete();
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
private:
|
||||
screen_device *m_screen;
|
||||
huc6270_device *m_huc6270_a;
|
||||
huc6270_device *m_huc6270_b;
|
||||
int m_last_h;
|
||||
int m_last_v;
|
||||
int m_height;
|
||||
|
||||
UINT16 m_palette[512];
|
||||
UINT16 m_address;
|
||||
UINT16 m_palette_latch;
|
||||
UINT16 m_register;
|
||||
UINT16 m_control;
|
||||
UINT8 m_priority[7];
|
||||
|
||||
UINT8 m_pixels_per_clock; /* Number of pixels to output per colour clock */
|
||||
UINT16 m_pixel_data;
|
||||
UINT8 m_pixel_clock;
|
||||
|
||||
emu_timer *m_timer;
|
||||
bitmap_rgb32 *m_bmp;
|
||||
};
|
||||
|
||||
|
||||
extern const device_type HUC6261;
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user