(MESS) sms/gamegear: misc improvements [Enik Land]

- Renamed the gear2gear port to EXT port, after reading the references
  in the official GG documents
- Invert Y1 pin signal bits: now high is 1 and low is 0;
- More complete Y1 behavior: goes low only for transparent pixels;
- Fix color of column 0 when it doesn't completely entered in the active display;
- Improve behavior of sprite overflow, to not be flagged when VINT is active.

out of whatsnew: the new Y1 pin behavior of the SMS VDP is based on Charles' findings and TMS9918 manual.
This commit is contained in:
etabeta78 2015-01-27 08:34:57 +01:00
parent 8028062f65
commit b4834b7595
10 changed files with 146 additions and 132 deletions

View File

@ -1291,12 +1291,12 @@ endif
#------------------------------------------------- #-------------------------------------------------
# #
#@src/emu/bus/gamegear/gear2gear.h,BUSES += GAMEGEAR #@src/emu/bus/gamegear/ggext.h,BUSES += GAMEGEAR
#------------------------------------------------- #-------------------------------------------------
ifneq ($(filter GAMEGEAR,$(BUSES)),) ifneq ($(filter GAMEGEAR,$(BUSES)),)
OBJDIRS += $(BUSOBJ)/gamegear OBJDIRS += $(BUSOBJ)/gamegear
BUSOBJS += $(BUSOBJ)/gamegear/gear2gear.o BUSOBJS += $(BUSOBJ)/gamegear/ggext.o
BUSOBJS += $(BUSOBJ)/gamegear/smsctrladp.o BUSOBJS += $(BUSOBJ)/gamegear/smsctrladp.o
endif endif

View File

@ -1,13 +1,13 @@
/********************************************************************** /**********************************************************************
Sega Game Gear "Gear to Gear Port" emulation Sega Game Gear EXT port emulation
Copyright MESS Team. Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions. Visit http://mamedev.org for licensing and usage restrictions.
**********************************************************************/ **********************************************************************/
#include "gear2gear.h" #include "ggext.h"
// slot devices // slot devices
#include "smsctrladp.h" #include "smsctrladp.h"
@ -17,7 +17,7 @@
// GLOBAL VARIABLES // GLOBAL VARIABLES
//************************************************************************** //**************************************************************************
const device_type GG_GEAR2GEAR_PORT = &device_creator<gg_gear2gear_port_device>; const device_type GG_EXT_PORT = &device_creator<gg_ext_port_device>;
@ -26,21 +26,21 @@ const device_type GG_GEAR2GEAR_PORT = &device_creator<gg_gear2gear_port_device>;
//************************************************************************** //**************************************************************************
//------------------------------------------------- //-------------------------------------------------
// device_gg_gear2gear_port_interface - constructor // device_gg_ext_port_interface - constructor
//------------------------------------------------- //-------------------------------------------------
device_gg_gear2gear_port_interface::device_gg_gear2gear_port_interface(const machine_config &mconfig, device_t &device) device_gg_ext_port_interface::device_gg_ext_port_interface(const machine_config &mconfig, device_t &device)
: device_slot_card_interface(mconfig,device) : device_slot_card_interface(mconfig,device)
{ {
m_port = dynamic_cast<gg_gear2gear_port_device *>(device.owner()); m_port = dynamic_cast<gg_ext_port_device *>(device.owner());
} }
//------------------------------------------------- //-------------------------------------------------
// ~device_gg_gear2gear_port_interface - destructor // ~device_gg_ext_port_interface - destructor
//------------------------------------------------- //-------------------------------------------------
device_gg_gear2gear_port_interface::~device_gg_gear2gear_port_interface() device_gg_ext_port_interface::~device_gg_ext_port_interface()
{ {
} }
@ -51,11 +51,11 @@ device_gg_gear2gear_port_interface::~device_gg_gear2gear_port_interface()
//************************************************************************** //**************************************************************************
//------------------------------------------------- //-------------------------------------------------
// gg_gear2gear_port_device - constructor // gg_ext_port_device - constructor
//------------------------------------------------- //-------------------------------------------------
gg_gear2gear_port_device::gg_gear2gear_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : gg_ext_port_device::gg_ext_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, GG_GEAR2GEAR_PORT, "Gear to Gear Port", tag, owner, clock, "gg_gear2gear_port", __FILE__), device_t(mconfig, GG_EXT_PORT, "EXT Port", tag, owner, clock, "gg_ext_port", __FILE__),
device_slot_interface(mconfig, *this), device_slot_interface(mconfig, *this),
m_th_pin_handler(*this), m_th_pin_handler(*this),
m_pixel_handler(*this) m_pixel_handler(*this)
@ -64,10 +64,10 @@ gg_gear2gear_port_device::gg_gear2gear_port_device(const machine_config &mconfig
//------------------------------------------------- //-------------------------------------------------
// gg_gear2gear_port_device - destructor // gg_ext_port_device - destructor
//------------------------------------------------- //-------------------------------------------------
gg_gear2gear_port_device::~gg_gear2gear_port_device() gg_ext_port_device::~gg_ext_port_device()
{ {
} }
@ -76,16 +76,16 @@ gg_gear2gear_port_device::~gg_gear2gear_port_device()
// device_start - device-specific startup // device_start - device-specific startup
//------------------------------------------------- //-------------------------------------------------
void gg_gear2gear_port_device::device_start() void gg_ext_port_device::device_start()
{ {
m_device = dynamic_cast<device_gg_gear2gear_port_interface *>(get_card_device()); m_device = dynamic_cast<device_gg_ext_port_interface *>(get_card_device());
m_th_pin_handler.resolve_safe(); m_th_pin_handler.resolve_safe();
m_pixel_handler.resolve_safe(0); m_pixel_handler.resolve_safe(0);
} }
UINT8 gg_gear2gear_port_device::port_r() UINT8 gg_ext_port_device::port_r()
{ {
UINT8 data = 0xff; UINT8 data = 0xff;
if (m_device) if (m_device)
@ -93,28 +93,28 @@ UINT8 gg_gear2gear_port_device::port_r()
return data; return data;
} }
void gg_gear2gear_port_device::port_w( UINT8 data ) void gg_ext_port_device::port_w( UINT8 data )
{ {
if (m_device) if (m_device)
m_device->peripheral_w(data); m_device->peripheral_w(data);
} }
void gg_gear2gear_port_device::th_pin_w(int state) void gg_ext_port_device::th_pin_w(int state)
{ {
m_th_pin_handler(state); m_th_pin_handler(state);
} }
UINT32 gg_gear2gear_port_device::pixel_r() UINT32 gg_ext_port_device::pixel_r()
{ {
return m_pixel_handler(); return m_pixel_handler();
} }
//------------------------------------------------- //-------------------------------------------------
// SLOT_INTERFACE( gg_gear2gear_port_devices ) // SLOT_INTERFACE( gg_ext_port_devices )
//------------------------------------------------- //-------------------------------------------------
SLOT_INTERFACE_START( gg_gear2gear_port_devices ) SLOT_INTERFACE_START( gg_ext_port_devices )
SLOT_INTERFACE("smsctrladp", SMS_CTRL_ADAPTOR) SLOT_INTERFACE("smsctrladp", SMS_CTRL_ADAPTOR)
SLOT_INTERFACE_END SLOT_INTERFACE_END

View File

@ -1,6 +1,6 @@
/********************************************************************** /**********************************************************************
Sega Game Gear "Gear to Gear Port" emulation Sega Game Gear EXT port emulation
Copyright MESS Team. Copyright MESS Team.
Visit http://mamedev.org for licensing and usage restrictions. Visit http://mamedev.org for licensing and usage restrictions.
@ -12,8 +12,8 @@
#pragma once #pragma once
#ifndef __GG_GEAR2GEAR_PORT__ #ifndef __GG_EXT_PORT__
#define __GG_GEAR2GEAR_PORT__ #define __GG_EXT_PORT__
#include "emu.h" #include "emu.h"
@ -23,19 +23,19 @@
// INTERFACE CONFIGURATION MACROS // INTERFACE CONFIGURATION MACROS
//************************************************************************** //**************************************************************************
#define MCFG_GG_GEAR2GEAR_PORT_ADD(_tag, _slot_intf, _def_slot) \ #define MCFG_GG_EXT_PORT_ADD(_tag, _slot_intf, _def_slot) \
MCFG_DEVICE_ADD(_tag, GG_GEAR2GEAR_PORT, 0) \ MCFG_DEVICE_ADD(_tag, GG_EXT_PORT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
#define MCFG_GG_GEAR2GEAR_PORT_MODIFY(_tag) \ #define MCFG_GG_EXT_PORT_MODIFY(_tag) \
MCFG_DEVICE_MODIFY(_tag) MCFG_DEVICE_MODIFY(_tag)
#define MCFG_GG_GEAR2GEAR_PORT_TH_INPUT_HANDLER(_devcb) \ #define MCFG_GG_EXT_PORT_TH_INPUT_HANDLER(_devcb) \
devcb = &gg_gear2gear_port_device::set_th_input_handler(*device, DEVCB_##_devcb); devcb = &gg_ext_port_device::set_th_input_handler(*device, DEVCB_##_devcb);
#define MCFG_GG_GEAR2GEAR_PORT_PIXEL_HANDLER(_devcb) \ #define MCFG_GG_EXT_PORT_PIXEL_HANDLER(_devcb) \
devcb = &gg_gear2gear_port_device::set_pixel_handler(*device, DEVCB_##_devcb); devcb = &gg_ext_port_device::set_pixel_handler(*device, DEVCB_##_devcb);
@ -43,27 +43,26 @@
// TYPE DEFINITIONS // TYPE DEFINITIONS
//************************************************************************** //**************************************************************************
// ======================> gg_gear2gear_port_device // ======================> gg_ext_port_device
class device_gg_gear2gear_port_interface; class device_gg_ext_port_interface;
class gg_gear2gear_port_device : public device_t, class gg_ext_port_device : public device_t,
public device_slot_interface public device_slot_interface
{ {
public: public:
// construction/destruction // construction/destruction
gg_gear2gear_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); gg_ext_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
virtual ~gg_gear2gear_port_device(); virtual ~gg_ext_port_device();
// static configuration helpers // static configuration helpers
template<class _Object> static devcb_base &set_th_input_handler(device_t &device, _Object object) { return downcast<gg_gear2gear_port_device &>(device).m_th_pin_handler.set_callback(object); } template<class _Object> static devcb_base &set_th_input_handler(device_t &device, _Object object) { return downcast<gg_ext_port_device &>(device).m_th_pin_handler.set_callback(object); }
template<class _Object> static devcb_base &set_pixel_handler(device_t &device, _Object object) { return downcast<gg_gear2gear_port_device &>(device).m_pixel_handler.set_callback(object); } template<class _Object> static devcb_base &set_pixel_handler(device_t &device, _Object object) { return downcast<gg_ext_port_device &>(device).m_pixel_handler.set_callback(object); }
// Currently, only the support for SMS Controller Adaptor is emulated, // Currently, only the support for SMS Controller Adaptor is emulated,
// for when SMS Compatibility mode is enabled. In that mode, the 10 // for when SMS Compatibility mode is enabled. In that mode, the 10 pins
// pins of the Gear to Gear Port follows the same numbering of a SMS // of the EXT port follows the same numbering of a SMS Control port.
// Control port.
// Data returned by the port_r methods: // Data returned by the port_r methods:
// bit 0 - pin 1 - Up // bit 0 - pin 1 - Up
@ -87,7 +86,7 @@ public:
// device-level overrides // device-level overrides
virtual void device_start(); virtual void device_start();
device_gg_gear2gear_port_interface *m_device; device_gg_ext_port_interface *m_device;
private: private:
devcb_write_line m_th_pin_handler; devcb_write_line m_th_pin_handler;
@ -95,29 +94,29 @@ private:
}; };
// ======================> device_gg_gear2gear_port_interface // ======================> device_gg_ext_port_interface
// class representing interface-specific live sms_expansion card // class representing interface-specific live sms_expansion card
class device_gg_gear2gear_port_interface : public device_slot_card_interface class device_gg_ext_port_interface : public device_slot_card_interface
{ {
public: public:
// construction/destruction // construction/destruction
device_gg_gear2gear_port_interface(const machine_config &mconfig, device_t &device); device_gg_ext_port_interface(const machine_config &mconfig, device_t &device);
virtual ~device_gg_gear2gear_port_interface(); virtual ~device_gg_ext_port_interface();
virtual UINT8 peripheral_r() { return 0xff; }; virtual UINT8 peripheral_r() { return 0xff; };
virtual void peripheral_w(UINT8 data) { }; virtual void peripheral_w(UINT8 data) { };
protected: protected:
gg_gear2gear_port_device *m_port; gg_ext_port_device *m_port;
}; };
// device type definition // device type definition
extern const device_type GG_GEAR2GEAR_PORT; extern const device_type GG_EXT_PORT;
SLOT_INTERFACE_EXTERN( gg_gear2gear_port_devices ); SLOT_INTERFACE_EXTERN( gg_ext_port_devices );
#endif #endif

View File

@ -1,6 +1,6 @@
/********************************************************************** /**********************************************************************
Sega Game Gear "Gear to Gear Port SMS Controller Adaptor" emulation Sega Game Gear "SMS Controller Adaptor" emulation
Also known as "Master Link" cable. Also known as "Master Link" cable.
Copyright MESS Team. Copyright MESS Team.
@ -29,7 +29,7 @@ const device_type SMS_CTRL_ADAPTOR = &device_creator<sms_ctrl_adaptor_device>;
sms_ctrl_adaptor_device::sms_ctrl_adaptor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : sms_ctrl_adaptor_device::sms_ctrl_adaptor_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, SMS_CTRL_ADAPTOR, "SMS Controller Adaptor", tag, owner, clock, "sms_ctrl_adaptor", __FILE__), device_t(mconfig, SMS_CTRL_ADAPTOR, "SMS Controller Adaptor", tag, owner, clock, "sms_ctrl_adaptor", __FILE__),
device_gg_gear2gear_port_interface(mconfig, *this), device_gg_ext_port_interface(mconfig, *this),
m_subctrl_port(*this, "ctrl") m_subctrl_port(*this, "ctrl")
{ {
} }

View File

@ -1,6 +1,6 @@
/********************************************************************** /**********************************************************************
Sega Game Gear "Gear to Gear Port SMS Controller Adaptor" emulation Sega Game Gear "SMS Controller Adaptor" emulation
Also known as "Master Link" cable. Also known as "Master Link" cable.
Copyright MESS Team. Copyright MESS Team.
@ -15,7 +15,7 @@
#include "emu.h" #include "emu.h"
#include "gear2gear.h" #include "ggext.h"
#include "../sms_ctrl/smsctrl.h" #include "../sms_ctrl/smsctrl.h"
@ -27,7 +27,7 @@
// ======================> sms_ctrl_adaptor_device // ======================> sms_ctrl_adaptor_device
class sms_ctrl_adaptor_device : public device_t, class sms_ctrl_adaptor_device : public device_t,
public device_gg_gear2gear_port_interface public device_gg_ext_port_interface
{ {
public: public:
// construction/destruction // construction/destruction
@ -41,7 +41,7 @@ protected:
virtual void device_start(); virtual void device_start();
virtual machine_config_constructor device_mconfig_additions() const; virtual machine_config_constructor device_mconfig_additions() const;
// device_gg_gear2gear_port_interface overrides // device_gg_ext_port_interface overrides
virtual UINT8 peripheral_r(); virtual UINT8 peripheral_r();
virtual void peripheral_w(UINT8 data); virtual void peripheral_w(UINT8 data);

View File

@ -14,6 +14,7 @@ To do:
- Display mode 1 (text) - Display mode 1 (text)
- Display mode 3 (multicolor) - Display mode 3 (multicolor)
- Sprite doubling bug of the 315-5124 chip - Sprite doubling bug of the 315-5124 chip
- Verify timing on the Game Gear (315-5378 chip)
SMS Display Timing SMS Display Timing
@ -343,7 +344,7 @@ void sega315_5124_device::device_timer(emu_timer &timer, device_timer_id id, int
rec.min_x = SEGA315_5124_LBORDER_START; rec.min_x = SEGA315_5124_LBORDER_START;
rec.max_x = SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 1; rec.max_x = SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 1;
m_tmpbitmap.fill(m_palette->pen(m_current_palette[BACKDROP_COLOR]), rec); m_tmpbitmap.fill(m_palette->pen(m_current_palette[BACKDROP_COLOR]), rec);
m_y1_bitmap.fill(1, rec); m_y1_bitmap.fill(( m_reg[0x07] & 0x0f ) ? 1 : 0, rec);
} }
break; break;
@ -358,7 +359,7 @@ void sega315_5124_device::device_timer(emu_timer &timer, device_timer_id id, int
rec.min_x = SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256; rec.min_x = SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256;
rec.max_x = rec.min_x + SEGA315_5124_RBORDER_WIDTH - 1; rec.max_x = rec.min_x + SEGA315_5124_RBORDER_WIDTH - 1;
m_tmpbitmap.fill(m_palette->pen(m_current_palette[BACKDROP_COLOR]), rec); m_tmpbitmap.fill(m_palette->pen(m_current_palette[BACKDROP_COLOR]), rec);
m_y1_bitmap.fill(1, rec); m_y1_bitmap.fill(( m_reg[0x07] & 0x0f ) ? 1 : 0, rec);
} }
break; break;
@ -847,18 +848,19 @@ void sega315_5124_device::draw_scanline_mode4( int *line_buffer, int *priority_s
//logerror("%x %x\n", pixel_plot_x, line); //logerror("%x %x\n", pixel_plot_x, line);
if (tile_column == 0 && (x_scroll & 0x07)) if (tile_column == 0 && (x_scroll & 0x07))
{ {
/* the VDP only draws the first column when it has completely entered /* when the first column hasn't completely entered in the screen, its
in the screen, else it is filled with the sprite pattern #0 */ background is filled only with color #0 of the selected palette */
line_buffer[pixel_plot_x] = m_current_palette[0x10]; line_buffer[pixel_plot_x] = m_current_palette[palette_selected ? 0x10 : 0x00];
priority_selected[pixel_plot_x] = priority_select;
} }
else else
{ {
line_buffer[pixel_plot_x] = m_current_palette[pen_selected]; line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
}
priority_selected[pixel_plot_x] = priority_select | (pen_selected & 0x0f); priority_selected[pixel_plot_x] = priority_select | (pen_selected & 0x0f);
} }
} }
} }
}
} }
@ -1012,7 +1014,8 @@ void sega315_5124_device::select_sprites( int line )
m_sprite_count = max_sprites; m_sprite_count = max_sprites;
if (line >= 0 && line < m_frame_timing[ACTIVE_DISPLAY_V]) /* Overflow is flagged only on active display and when VINT isn't active */
if (!(m_status & STATUS_VINT) && line >= 0 && line < m_frame_timing[ACTIVE_DISPLAY_V])
{ {
m_pending_status |= STATUS_SPROVR; m_pending_status |= STATUS_SPROVR;
} }
@ -1030,7 +1033,8 @@ void sega315_5124_device::draw_sprites_mode4( int *line_buffer, int *priority_se
if (m_display_disabled || m_sprite_count == 0) if (m_display_disabled || m_sprite_count == 0)
return; return;
/* Sprites aren't drawn and collisions don't occur on column 0 if it is disabled */ /* Sprites aren't drawn and collisions don't occur on column 0 if it is disabled.
Note: On Megadrive/Genesis VDP, collisions occur on the disabled column 0. */
if (m_reg[0x00] & 0x20) if (m_reg[0x00] & 0x20)
plot_min_x = 8; plot_min_x = 8;
@ -1084,6 +1088,8 @@ void sega315_5124_device::draw_sprites_mode4( int *line_buffer, int *priority_se
continue; continue;
} }
/* Draw sprite pixel */
/* Check if the background has lower priority */
if (!(priority_selected[pixel_plot_x] & PRIORITY_BIT)) if (!(priority_selected[pixel_plot_x] & PRIORITY_BIT))
{ {
line_buffer[pixel_plot_x] = m_current_palette[pen_selected]; line_buffer[pixel_plot_x] = m_current_palette[pen_selected];
@ -1296,10 +1302,11 @@ void sega315_5124_device::draw_scanline( int pixel_offset_x, int pixel_plot_y, i
if ( line < m_frame_timing[ACTIVE_DISPLAY_V] ) if ( line < m_frame_timing[ACTIVE_DISPLAY_V] )
{ {
memset(priority_selected, 1, sizeof(priority_selected));
switch( m_vdp_mode ) switch( m_vdp_mode )
{ {
case 0: case 0:
memset(priority_selected, 1, sizeof(priority_selected));
if ( line >= 0 ) if ( line >= 0 )
{ {
draw_scanline_mode0( blitline_buffer, line ); draw_scanline_mode0( blitline_buffer, line );
@ -1311,7 +1318,6 @@ void sega315_5124_device::draw_scanline( int pixel_offset_x, int pixel_plot_y, i
break; break;
case 2: case 2:
memset(priority_selected, 1, sizeof(priority_selected));
if ( line >= 0 ) if ( line >= 0 )
{ {
draw_scanline_mode2( blitline_buffer, line ); draw_scanline_mode2( blitline_buffer, line );
@ -1324,7 +1330,6 @@ void sega315_5124_device::draw_scanline( int pixel_offset_x, int pixel_plot_y, i
case 4: case 4:
default: default:
memset(priority_selected, 0, sizeof(priority_selected));
if ( line >= 0 ) if ( line >= 0 )
{ {
draw_scanline_mode4( blitline_buffer, priority_selected, line ); draw_scanline_mode4( blitline_buffer, priority_selected, line );
@ -1346,7 +1351,7 @@ void sega315_5124_device::draw_scanline( int pixel_offset_x, int pixel_plot_y, i
rec.min_x = pixel_offset_x; rec.min_x = pixel_offset_x;
rec.max_x = pixel_offset_x + 255; rec.max_x = pixel_offset_x + 255;
m_tmpbitmap.fill(m_palette->pen(m_current_palette[BACKDROP_COLOR]), rec); m_tmpbitmap.fill(m_palette->pen(m_current_palette[BACKDROP_COLOR]), rec);
m_y1_bitmap.fill(1, rec); m_y1_bitmap.fill(( m_reg[0x07] & 0x0f ) ? 1 : 0, rec);
} }
else else
{ {
@ -1361,13 +1366,13 @@ void sega315_5124_device::blit_scanline( int *line_buffer, int *priority_selecte
UINT8 *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x); UINT8 *p_y1 = &m_y1_bitmap.pix8(pixel_plot_y + line, pixel_offset_x);
int x = 0; int x = 0;
if (m_vdp_mode == 4 && m_reg[0x00] & 0x20) if (m_vdp_mode == 4 && (m_reg[0x00] & 0x20))
{ {
/* Fill column 0 with overscan color from m_reg[0x07] */ /* Fill column 0 with overscan color from m_reg[0x07] */
do do
{ {
p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]); p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
p_y1[x] = 1; p_y1[x] = ( m_reg[0x07] & 0x0f ) ? 1 : 0;
} }
while(++x < 8); while(++x < 8);
} }
@ -1375,7 +1380,7 @@ void sega315_5124_device::blit_scanline( int *line_buffer, int *priority_selecte
do do
{ {
p_bitmap[x] = m_palette->pen(line_buffer[x]); p_bitmap[x] = m_palette->pen(line_buffer[x]);
p_y1[x] = ( priority_selected[x] & 0x0f ) ? 0 : 1; p_y1[x] = ( priority_selected[x] & 0x0f ) ? 1 : 0;
} }
while(++x < 256); while(++x < 256);
} }
@ -1397,7 +1402,7 @@ void sega315_5378_device::blit_scanline( int *line_buffer, int *priority_selecte
do do
{ {
p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]); p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
p_y1[x] = 1; // not verified p_y1[x] = ( m_reg[0x07] & 0x0f ) ? 1 : 0;
} }
while (++x < 48); while (++x < 48);
@ -1406,7 +1411,7 @@ void sega315_5378_device::blit_scanline( int *line_buffer, int *priority_selecte
do do
{ {
p_bitmap[x] = m_palette->pen(line_buffer[x]); p_bitmap[x] = m_palette->pen(line_buffer[x]);
p_y1[x] = ( priority_selected[x] & 0x0f ) ? 0 : 1; p_y1[x] = ( priority_selected[x] & 0x0f ) ? 1 : 0;
} }
while (++x < 208); while (++x < 208);
} }
@ -1416,7 +1421,7 @@ void sega315_5378_device::blit_scanline( int *line_buffer, int *priority_selecte
do do
{ {
p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]); p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
p_y1[x] = 1; // not verified p_y1[x] = ( m_reg[0x07] & 0x0f ) ? 1 : 0;
} }
while (++x < 208); while (++x < 208);
} }
@ -1425,7 +1430,7 @@ void sega315_5378_device::blit_scanline( int *line_buffer, int *priority_selecte
do do
{ {
p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]); p_bitmap[x] = m_palette->pen(m_current_palette[BACKDROP_COLOR]);
p_y1[x] = 1; // not verified p_y1[x] = ( m_reg[0x07] & 0x0f ) ? 1 : 0;
} }
while (++x < 256); while (++x < 256);
} }

View File

@ -956,8 +956,8 @@ UINT32 systeme_state::screen_update_systeme(screen_device &screen, bitmap_rgb32
for ( int x = cliprect.min_x; x <= cliprect.max_x; x++ ) for ( int x = cliprect.min_x; x <= cliprect.max_x; x++ )
{ {
dest_ptr[x] = ( y1_ptr[x] ) ? vdp1_ptr[x] : vdp2_ptr[x]; dest_ptr[x] = ( y1_ptr[x] ) ? vdp2_ptr[x] : vdp1_ptr[x];
//dest_ptr[x] = y1_ptr[x] ? 0xFF0000 : 0x00FF00; //dest_ptr[x] = y1_ptr[x] ? 0x00FF00 : 0xFF0000;
} }
} }

View File

@ -14,6 +14,7 @@
- SIO interface for Game Gear (needs netplay, I guess) - SIO interface for Game Gear (needs netplay, I guess)
- Sega Demo Unit II (kiosk expansion device) - Sega Demo Unit II (kiosk expansion device)
- SMS 8 slot game changer (kiosk expansion device)
- SMS Disk System (floppy disk drive expansion device) - unreleased - SMS Disk System (floppy disk drive expansion device) - unreleased
- Rapid button of Japanese Master System - Rapid button of Japanese Master System
- Keyboard support for Sega Mark III (sg1000m3 driver) - Keyboard support for Sega Mark III (sg1000m3 driver)
@ -57,15 +58,15 @@ General compatibility issues on real hardware (not emulation bugs):
- Few games of the ones with FM support need to detect the system region as - Few games of the ones with FM support need to detect the system region as
Japanese to play FM sound; Japanese to play FM sound;
- The Light Phaser gun doesn't work with the Japanese SMS; - The Light Phaser gun doesn't work with the Japanese SMS;
- There are reports about Light Phaser working on the second Korean console - There are reports about Light Phaser working on the second Korean SMS
version, and a Korean advert shows support on the first version (Gam*Boy I, version, and a Korean advert shows support on the first version (Gam*Boy I,
although based on Japanese SMS); although based on Japanese SMS);
- The Korean SMS versions have Japanese-format cartridge slot, but only on the - The Korean SMS versions have Japanese-format cartridge slot, but only on the
first (Gam*Boy I) the region is detected as Japanese; first (Gam*Boy I) the region is detected as Japanese;
- Some SMS ROMs don't run when are plugged-in to SMS expansion slot, through - Some SMS ROMs don't run when are plugged-in to SMS expansion slot, through
the gender adapter; the gender adapter;
- Some SMS ROMs don't run when are plugged-in to a Game Gear, through the - Some SMS ROMs don't run or have issues when are plugged-in to a Game Gear,
Master Gear adapter; through the Master Gear adapter;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -405,6 +406,13 @@ static INPUT_PORTS_START( smsj )
INPUT_PORTS_END INPUT_PORTS_END
static INPUT_PORTS_START( smssdisp ) static INPUT_PORTS_START( smssdisp )
// For each peripheral port (for controllers or 3-D glasses), there are sets
// of two connectors wired in parallel on the real hardware. This allows to
// have different controllers, like a pad and a Light Phaser, plugged together
// for a player input, what avoids having to re-plug them every time a game is
// changed to another that requires a different controller. Also, this allows
// 3-D games to be properly watched by two persons at same time.
// For now the driver just uses single input ports.
PORT_INCLUDE( sms1 ) PORT_INCLUDE( sms1 )
PORT_START("DSW") PORT_START("DSW")
@ -805,9 +813,9 @@ static MACHINE_CONFIG_START( gamegear, sms_state )
MCFG_SOFTWARE_LIST_ADD("cart_list", "gamegear") MCFG_SOFTWARE_LIST_ADD("cart_list", "gamegear")
MCFG_GG_GEAR2GEAR_PORT_ADD("gear2gear", gg_gear2gear_port_devices, NULL) MCFG_GG_EXT_PORT_ADD("ext", gg_ext_port_devices, NULL)
MCFG_GG_GEAR2GEAR_PORT_TH_INPUT_HANDLER(WRITELINE(sms_state, sms_ctrl2_th_input)) // not verified MCFG_GG_EXT_PORT_TH_INPUT_HANDLER(WRITELINE(sms_state, sms_ctrl2_th_input)) // not verified
//MCFG_GG_GEAR2GEAR_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) // only for GG-TV mod //MCFG_GG_EXT_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) // only for GG-TV mod
MACHINE_CONFIG_END MACHINE_CONFIG_END

View File

@ -19,7 +19,7 @@
#define CONTROL1_TAG "ctrl1" #define CONTROL1_TAG "ctrl1"
#define CONTROL2_TAG "ctrl2" #define CONTROL2_TAG "ctrl2"
#include "bus/gamegear/gear2gear.h" #include "bus/gamegear/ggext.h"
#include "bus/sms_ctrl/smsctrl.h" #include "bus/sms_ctrl/smsctrl.h"
#include "bus/sms_exp/smsexp.h" #include "bus/sms_exp/smsexp.h"
#include "bus/sega8/sega8_slot.h" #include "bus/sega8/sega8_slot.h"
@ -37,7 +37,7 @@ public:
m_region_maincpu(*this, "maincpu"), m_region_maincpu(*this, "maincpu"),
m_port_ctrl1(*this, CONTROL1_TAG), m_port_ctrl1(*this, CONTROL1_TAG),
m_port_ctrl2(*this, CONTROL2_TAG), m_port_ctrl2(*this, CONTROL2_TAG),
m_port_gear2gear(*this, "gear2gear"), m_port_gg_ext(*this, "ext"),
m_port_gg_dc(*this, "GG_PORT_DC"), m_port_gg_dc(*this, "GG_PORT_DC"),
m_port_pause(*this, "PAUSE"), m_port_pause(*this, "PAUSE"),
m_port_reset(*this, "RESET"), m_port_reset(*this, "RESET"),
@ -66,7 +66,7 @@ public:
required_memory_region m_region_maincpu; required_memory_region m_region_maincpu;
optional_device<sms_control_port_device> m_port_ctrl1; optional_device<sms_control_port_device> m_port_ctrl1;
optional_device<sms_control_port_device> m_port_ctrl2; optional_device<sms_control_port_device> m_port_ctrl2;
optional_device<gg_gear2gear_port_device> m_port_gear2gear; optional_device<gg_ext_port_device> m_port_gg_ext;
optional_ioport m_port_gg_dc; optional_ioport m_port_gg_dc;
optional_ioport m_port_pause; optional_ioport m_port_pause;
optional_ioport m_port_reset; optional_ioport m_port_reset;
@ -75,25 +75,15 @@ public:
optional_ioport m_port_scope_binocular; optional_ioport m_port_scope_binocular;
optional_ioport m_port_persist; optional_ioport m_port_persist;
device_t *m_left_lcd;
device_t *m_right_lcd;
address_space *m_space; address_space *m_space;
UINT8 m_bios_page_count;
UINT8 m_fm_detect;
UINT8 m_io_ctrl_reg;
int m_paused;
UINT8 m_mem_ctrl_reg;
UINT8 m_mem_device_enabled;
UINT8 *m_mainram; UINT8 *m_mainram;
UINT8 *m_BIOS; UINT8 *m_BIOS;
UINT8 m_mapper[4];
UINT8 m_port_dc_reg;
UINT8 m_port_dd_reg;
UINT8 m_gg_sio[5];
// [0] for 0x400-0x3fff, [1] for 0x4000-0x7fff, [2] for 0x8000-0xffff, [3] for 0x0000-0x0400 // for 3D glass binocular hack
UINT8 m_bios_page[4]; device_t *m_left_lcd;
device_t *m_right_lcd;
bitmap_rgb32 m_prevleft_bitmap;
bitmap_rgb32 m_prevright_bitmap;
// for gamegear LCD persistence hack // for gamegear LCD persistence hack
bitmap_rgb32 m_prev_bitmap; bitmap_rgb32 m_prev_bitmap;
@ -105,10 +95,6 @@ public:
// vertical scaling in the gamegear sms compatibility mode. // vertical scaling in the gamegear sms compatibility mode.
int *m_line_buffer; int *m_line_buffer;
// for 3D glass binocular hack
bitmap_rgb32 m_prevleft_bitmap;
bitmap_rgb32 m_prevright_bitmap;
// model identifiers // model identifiers
UINT8 m_is_gamegear; UINT8 m_is_gamegear;
UINT8 m_is_gg_region_japan; UINT8 m_is_gg_region_japan;
@ -121,6 +107,20 @@ public:
UINT8 m_has_fm; UINT8 m_has_fm;
UINT8 m_has_jpn_sms_cart_slot; UINT8 m_has_jpn_sms_cart_slot;
// [0] for 0x400-0x3fff, [1] for 0x4000-0x7fff, [2] for 0x8000-0xffff, [3] for 0x0000-0x0400
UINT8 m_bios_page[4];
UINT8 m_bios_page_count;
UINT8 m_mapper[4];
UINT8 m_io_ctrl_reg;
UINT8 m_mem_ctrl_reg;
UINT8 m_mem_device_enabled;
UINT8 m_fm_detect;
UINT8 m_port_dc_reg;
UINT8 m_port_dd_reg;
UINT8 m_gg_sio[5];
int m_paused;
// Data needed for Light Phaser // Data needed for Light Phaser
UINT8 m_ctrl1_th_state; UINT8 m_ctrl1_th_state;
UINT8 m_ctrl2_th_state; UINT8 m_ctrl2_th_state;
@ -132,32 +132,19 @@ public:
UINT8 m_sscope_state; UINT8 m_sscope_state;
UINT8 m_frame_sscope_state; UINT8 m_frame_sscope_state;
// slot devices
sega8_cart_slot_device *m_cartslot; sega8_cart_slot_device *m_cartslot;
sega8_card_slot_device *m_cardslot; sega8_card_slot_device *m_cardslot;
sms_expansion_slot_device *m_expslot; sms_expansion_slot_device *m_expslot;
// these are only used by the Store Display unit, but we keep them here temporarily to avoid the need of separate start/reset // these are only used by the Store Display unit, but we keep them here temporarily to avoid the need of separate start/reset
UINT8 m_store_control;
UINT8 m_store_cart_selection_data;
sega8_cart_slot_device *m_slots[16]; sega8_cart_slot_device *m_slots[16];
sega8_card_slot_device *m_cards[16]; sega8_card_slot_device *m_cards[16];
UINT8 m_store_control;
UINT8 m_store_cart_selection_data;
void store_post_load(); void store_post_load();
void store_select_cart(UINT8 data); void store_select_cart(UINT8 data);
/* Cartridge slot info */
DECLARE_WRITE8_MEMBER(sms_fm_detect_w);
DECLARE_READ8_MEMBER(sms_fm_detect_r);
DECLARE_WRITE8_MEMBER(sms_io_control_w);
DECLARE_READ8_MEMBER(sms_count_r);
DECLARE_READ8_MEMBER(sms_input_port_dc_r);
DECLARE_READ8_MEMBER(sms_input_port_dd_r);
DECLARE_READ8_MEMBER(gg_input_port_00_r);
DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w);
DECLARE_READ8_MEMBER(sms_sscope_r);
DECLARE_WRITE8_MEMBER(sms_sscope_w);
DECLARE_READ8_MEMBER(sms_mapper_r);
DECLARE_READ8_MEMBER(read_0000); DECLARE_READ8_MEMBER(read_0000);
DECLARE_READ8_MEMBER(read_4000); DECLARE_READ8_MEMBER(read_4000);
DECLARE_READ8_MEMBER(read_8000); DECLARE_READ8_MEMBER(read_8000);
@ -165,10 +152,29 @@ public:
DECLARE_WRITE8_MEMBER(write_ram); DECLARE_WRITE8_MEMBER(write_ram);
DECLARE_WRITE8_MEMBER(write_cart); DECLARE_WRITE8_MEMBER(write_cart);
DECLARE_READ8_MEMBER(sms_mapper_r);
DECLARE_WRITE8_MEMBER(sms_mapper_w); DECLARE_WRITE8_MEMBER(sms_mapper_w);
DECLARE_WRITE8_MEMBER(sms_mem_control_w); DECLARE_WRITE8_MEMBER(sms_mem_control_w);
DECLARE_WRITE8_MEMBER(sms_io_control_w);
DECLARE_READ8_MEMBER(sms_count_r);
DECLARE_READ8_MEMBER(sms_input_port_dc_r);
DECLARE_READ8_MEMBER(sms_input_port_dd_r);
DECLARE_READ8_MEMBER(gg_input_port_00_r);
DECLARE_WRITE8_MEMBER(gg_sio_w); DECLARE_WRITE8_MEMBER(gg_sio_w);
DECLARE_READ8_MEMBER(gg_sio_r); DECLARE_READ8_MEMBER(gg_sio_r);
DECLARE_WRITE8_MEMBER(sms_fm_detect_w);
DECLARE_READ8_MEMBER(sms_fm_detect_r);
DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w);
DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w);
DECLARE_READ8_MEMBER(sms_sscope_r);
DECLARE_WRITE8_MEMBER(sms_sscope_w);
DECLARE_WRITE_LINE_MEMBER(sms_int_callback);
DECLARE_WRITE_LINE_MEMBER(sms_pause_callback);
DECLARE_WRITE_LINE_MEMBER(sms_ctrl1_th_input);
DECLARE_WRITE_LINE_MEMBER(sms_ctrl2_th_input);
DECLARE_READ32_MEMBER(sms_pixel_color);
DECLARE_DRIVER_INIT(sg1000m3); DECLARE_DRIVER_INIT(sg1000m3);
DECLARE_DRIVER_INIT(gamegear); DECLARE_DRIVER_INIT(gamegear);
DECLARE_DRIVER_INIT(gamegeaj); DECLARE_DRIVER_INIT(gamegeaj);
@ -183,16 +189,12 @@ public:
DECLARE_VIDEO_RESET(gamegear); DECLARE_VIDEO_RESET(gamegear);
DECLARE_VIDEO_START(sms1); DECLARE_VIDEO_START(sms1);
DECLARE_VIDEO_RESET(sms1); DECLARE_VIDEO_RESET(sms1);
void screen_gg_sms_mode_scaling(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
UINT32 screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
UINT32 screen_update_sms(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); UINT32 screen_update_sms(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
UINT32 screen_update_sms1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); UINT32 screen_update_sms1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
UINT32 screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void screen_gg_sms_mode_scaling(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void screen_vblank_sms1(screen_device &screen, bool state); void screen_vblank_sms1(screen_device &screen, bool state);
DECLARE_WRITE_LINE_MEMBER(sms_int_callback);
DECLARE_WRITE_LINE_MEMBER(sms_pause_callback);
DECLARE_READ32_MEMBER(sms_pixel_color);
DECLARE_WRITE_LINE_MEMBER(sms_ctrl1_th_input);
DECLARE_WRITE_LINE_MEMBER(sms_ctrl2_th_input);
protected: protected:
UINT8 read_bus(address_space &space, unsigned int bank, UINT16 base_addr, UINT16 offset); UINT8 read_bus(address_space &space, unsigned int bank, UINT16 base_addr, UINT16 offset);

View File

@ -94,7 +94,7 @@ void sms_state::sms_get_inputs()
data1 = m_port_gg_dc->read(); data1 = m_port_gg_dc->read();
m_port_dc_reg &= ~0x03f | data1; m_port_dc_reg &= ~0x03f | data1;
data2 = m_port_gear2gear->port_r(); data2 = m_port_gg_ext->port_r();
} }
else else
{ {
@ -207,7 +207,7 @@ WRITE8_MEMBER(sms_state::sms_io_control_w)
if (!m_is_gamegear) if (!m_is_gamegear)
m_port_ctrl2->port_w(ctrl2_port_data); m_port_ctrl2->port_w(ctrl2_port_data);
else else
m_port_gear2gear->port_w(ctrl2_port_data); // not verified m_port_gg_ext->port_w(ctrl2_port_data); // not verified
} }
// check if TH is set to input (1). // check if TH is set to input (1).
if (data & 0x08) if (data & 0x08)
@ -215,7 +215,7 @@ WRITE8_MEMBER(sms_state::sms_io_control_w)
if (!m_is_gamegear) if (!m_is_gamegear)
ctrl2_port_data &= ~0x40 | m_port_ctrl2->port_r(); ctrl2_port_data &= ~0x40 | m_port_ctrl2->port_r();
else else
ctrl2_port_data &= ~0x40 | m_port_gear2gear->port_r(); // not verified ctrl2_port_data &= ~0x40 | m_port_gg_ext->port_r(); // not verified
// check if TH input level is high (1) and was output/low (0) // check if TH input level is high (1) and was output/low (0)
if ((ctrl2_port_data & 0x40) && !(m_io_ctrl_reg & 0x88)) if ((ctrl2_port_data & 0x40) && !(m_io_ctrl_reg & 0x88))