summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Wilbert Pol <wilbert@jdg.info>2012-08-20 20:15:14 +0000
committer Wilbert Pol <wilbert@jdg.info>2012-08-20 20:15:14 +0000
commit695fef3595327ddd102550e9dc4c6472c1b36d08 (patch)
tree6c46e45401b35a6fe620aea8286193e36a93e212
parent857f3e767b17278c510faa8879b14c9584513134 (diff)
Sync with MESS (nw)
-rw-r--r--.gitattributes2
-rw-r--r--src/emu/emu.mak1
-rw-r--r--src/emu/video/huc6261.c409
-rw-r--r--src/emu/video/huc6261.h83
4 files changed, 495 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes
index ec2c0266b8c..6770531efdf 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -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
diff --git a/src/emu/emu.mak b/src/emu/emu.mak
index 2c77f1f1261..6f5778eb7f2 100644
--- a/src/emu/emu.mak
+++ b/src/emu/emu.mak
@@ -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 \
diff --git a/src/emu/video/huc6261.c b/src/emu/video/huc6261.c
new file mode 100644
index 00000000000..dab3a97839a
--- /dev/null
+++ b/src/emu/video/huc6261.c
@@ -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 ) );
+}
+
diff --git a/src/emu/video/huc6261.h b/src/emu/video/huc6261.h
new file mode 100644
index 00000000000..a4c49b23751
--- /dev/null
+++ b/src/emu/video/huc6261.h
@@ -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