wiz cleanup round and a couple of fixes (sound problem and gaps in sprites)

This commit is contained in:
Michaël Banaan Ananas 2014-03-06 21:07:43 +00:00
parent d6c07e4ca4
commit 36c238fb0c
3 changed files with 493 additions and 408 deletions

View File

@ -1,15 +1,20 @@
/*************************************************************************** /***************************************************************************
Wiz/Stinger/Scion/Kung-Fu Taikun memory map (preliminary) Seibu Stinger/Wiz hardware
Driver by Zsolt Vasvari Driver by Zsolt Vasvari
XTAL: 18.432MHz??
2xZ80, 3xAY8910 (stinger/scion have 2xAY8910 + discrete sound)
These boards are similar to a Galaxian board in the way it handles scrolling These boards are similar to a Galaxian board in the way it handles scrolling
and sprites, but the similarities pretty much end there. The most notable and sprites, but the similarities pretty much end there. The most notable
difference is that there are 2 independently scrollable playfields. difference is that there are 2 independently scrollable playfields.
Wiz/Stinger/Scion/Kung-Fu Taikun memory map (preliminary)
Main CPU: Main CPU:
0000-BFFF ROM 0000-BFFF ROM
@ -66,25 +71,30 @@ I/O write:
7000 NMI enable (Wiz) 7000 NMI enable (Wiz)
****************************************************************************
TODO: TODO:
- Verify sprite colors in stinger/scion - Verify sprite colors in stinger/scion
- Global palette is wrong in stinger/scion compared to pcb, or could it be
due to gamma/hue?
- cpu/video/interrupt frequency measurements
- sprite-sprite priorities are not correct yet, eg:
* stinger popcorn enemies at beginning of the game should have higher priority
than that 'vacuum cleaner' enemy sphere,
* the cloud in kungfut should have higher prio than player char
- Improve stinger/scion discrete sound
- Background noise in scion (but not scionc). Note that the sound program is - Background noise in scion (but not scionc). Note that the sound program is
almost identical, except for three patches affecting noise period, noise almost identical, except for three patches affecting noise period, noise
channel C enable and channel C volume. So it looks just like a bug in the channel C enable and channel C volume. So it looks just like a bug in the
original (weird), or some strange form of protection. original (weird), or some strange form of protection.
Another possible assumption is that it has a nonstandard AY hookup, where - Is wiz protection emulation complete?
channel C is not directly mixed with channels A and B but is either - Wiz: the supplier of the screenshot says there still may be some wrong
disconnected or gated by something else first or filtered. scionc on the
other hand is a 'normal' hookup.
Wiz:
- Possible sprite/char priority issues.
- And the supplier of the screenshot says there still may be some wrong
colors. Just before the break on Level 2 there is a cresent moon, colors. Just before the break on Level 2 there is a cresent moon,
the background should probably be black. the background should probably be black.
2001-Jun-24 Fixed protection and added save states (SJ)
****************************************************************************
2002-Nov-30 Kung-Fu Taikun added 2002-Nov-30 Kung-Fu Taikun added
2xZ80 , 3x AY8910 2xZ80 , 3x AY8910
@ -98,8 +108,8 @@ Notes:
The microphone is for summoning clouds. The game falls back to use The microphone is for summoning clouds. The game falls back to use
buttons if it's not functioning. buttons if it's not functioning.
2003-JUL-30 updated Scion/Stinger analogue sound framework (AT)
****************************************************************************
Stephh's notes (based on the games Z80 code and some tests) : Stephh's notes (based on the games Z80 code and some tests) :
@ -166,35 +176,106 @@ Stephh's notes (based on the games Z80 code and some tests) :
#include "sound/discrete.h" #include "sound/discrete.h"
#include "includes/wiz.h" #include "includes/wiz.h"
/***************************************************************************
Stinger/Scion discrete sound
***************************************************************************/
#define STINGER_SHOT_EN1 NODE_01 #define STINGER_SHOT_EN1 NODE_01
#define STINGER_SHOT_EN2 NODE_02 #define STINGER_SHOT_EN2 NODE_02
#define STINGER_BOOM_EN1 NODE_03 #define STINGER_BOOM_EN1 NODE_03
#define STINGER_BOOM_EN2 NODE_04 #define STINGER_BOOM_EN2 NODE_04
// cut-and-pasted from Asteroid
WRITE8_MEMBER(wiz_state::sound_command_w) static const discrete_lfsr_desc stinger_lfsr =
{ {
switch (offset) DISC_CLK_IS_FREQ,
{ 16, /* Bit Length */
// 0x90 triggers a jump to non-existant address(development system?) and must be filtered 0, /* Reset Value */
case 0x00: 6, /* Use Bit 6 as XOR input 0 */
if (data != 0x90) soundlatch_byte_w(space, 0, data); 14, /* Use Bit 14 as XOR input 1 */
break; DISC_LFSR_XNOR, /* Feedback stage1 is XNOR */
DISC_LFSR_OR, /* Feedback stage2 is just stage 1 output OR with external feed */
DISC_LFSR_REPLACE, /* Feedback stage3 replaces the shifted register contents */
0x000001, /* Everything is shifted into the first bit only */
0, /* Output is already inverted by XNOR */
16 /* Output bit is feedback bit */
};
static DISCRETE_SOUND_START(stinger)
#define STINGER_SHOT_OUT NODE_90
#define STINGER_BOOM_OUT NODE_91
#define STINGER_FINAL_MIX NODE_99
// triggers are interleaved to give each circuit sufficient time to reset
DISCRETE_INPUT_LOGIC (STINGER_SHOT_EN1) // even-inteval shots
DISCRETE_INPUT_LOGIC (STINGER_SHOT_EN2) // odd-inteval shots
DISCRETE_INPUT_LOGIC (STINGER_BOOM_EN1) // even-inteval explosions
DISCRETE_INPUT_LOGIC (STINGER_BOOM_EN2) // odd-inteval explosions
//---------------------------------------
// Sample Shot Sound Circuit
#define SHOT_IN1 NODE_11
#define SHOT_IN2 NODE_12
#define SHOT_MOD NODE_13
#define SHOT_FRQ NODE_14
#define SHOT_AMP NODE_15
DISCRETE_RCDISC (SHOT_IN1, STINGER_SHOT_EN1, 1.0, 0.2, 1.0)
DISCRETE_RCDISC (SHOT_IN2, STINGER_SHOT_EN2, 1.0, 0.2, 1.0)
DISCRETE_SWITCH (SHOT_MOD, 1, STINGER_SHOT_EN1, SHOT_IN2, SHOT_IN1)
DISCRETE_MULTIPLY (SHOT_FRQ, SHOT_MOD, 2000)
DISCRETE_MULTIPLY (SHOT_AMP, SHOT_MOD, 800)
DISCRETE_SQUAREWAVE (STINGER_SHOT_OUT, 1, SHOT_FRQ, SHOT_AMP, 50, 0, 0)
//---------------------------------------
// Sample Explosion Sound Circuit
#define BOOM_IN1 NODE_21
#define BOOM_IN2 NODE_22
#define BOOM_MOD NODE_23
#define BOOM_AMP NODE_24
DISCRETE_RCDISC (BOOM_IN1, STINGER_BOOM_EN1, 1.0, 0.25, 1.0)
DISCRETE_RCDISC (BOOM_IN2, STINGER_BOOM_EN2, 1.0, 0.25, 1.0)
DISCRETE_SWITCH (BOOM_MOD, 1, STINGER_BOOM_EN1, BOOM_IN2, BOOM_IN1)
DISCRETE_MULTIPLY (BOOM_AMP, BOOM_MOD, 1500)
DISCRETE_LFSR_NOISE (STINGER_BOOM_OUT, 1, 1, 1800, BOOM_AMP, 0, 0, &stinger_lfsr)
//---------------------------------------
DISCRETE_ADDER2 (STINGER_FINAL_MIX, 1, STINGER_SHOT_OUT, STINGER_BOOM_OUT)
DISCRETE_OUTPUT (STINGER_FINAL_MIX, 5)
DISCRETE_SOUND_END
WRITE8_MEMBER(wiz_state::stinger_explosion_w)
{
// explosion sound trigger(analog?) // explosion sound trigger(analog?)
case 0x08:
discrete_sound_w(m_discrete, space, STINGER_BOOM_EN1, m_dsc1); discrete_sound_w(m_discrete, space, STINGER_BOOM_EN1, m_dsc1);
discrete_sound_w(m_discrete, space, STINGER_BOOM_EN2, m_dsc1^=1); discrete_sound_w(m_discrete, space, STINGER_BOOM_EN2, m_dsc1^=1);
break; }
WRITE8_MEMBER(wiz_state::stinger_shot_w)
{
// player shot sound trigger(analog?) // player shot sound trigger(analog?)
case 0x0a:
discrete_sound_w(m_discrete, space, STINGER_SHOT_EN1, m_dsc0); discrete_sound_w(m_discrete, space, STINGER_SHOT_EN1, m_dsc0);
discrete_sound_w(m_discrete, space, STINGER_SHOT_EN2, m_dsc0^=1); discrete_sound_w(m_discrete, space, STINGER_SHOT_EN2, m_dsc0^=1);
break;
}
} }
/***************************************************************************
I/O, Memory maps
***************************************************************************/
READ8_MEMBER(wiz_state::wiz_protection_r) READ8_MEMBER(wiz_state::wiz_protection_r)
{ {
switch (m_colorram2[0]) switch (m_colorram2[0])
@ -209,7 +290,7 @@ READ8_MEMBER(wiz_state::wiz_protection_r)
WRITE8_MEMBER(wiz_state::wiz_coin_counter_w) WRITE8_MEMBER(wiz_state::wiz_coin_counter_w)
{ {
coin_counter_w(machine(), offset,data); coin_counter_w(machine(), offset, data & 1);
} }
WRITE8_MEMBER(wiz_state::wiz_main_nmi_mask_w) WRITE8_MEMBER(wiz_state::wiz_main_nmi_mask_w)
@ -217,64 +298,117 @@ WRITE8_MEMBER(wiz_state::wiz_main_nmi_mask_w)
m_main_nmi_mask = data & 1; m_main_nmi_mask = data & 1;
} }
static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, wiz_state ) WRITE8_MEMBER(wiz_state::wiz_soundlatch_w)
{
// shift in soundlatch
if (m_sound_shiftptr < m_sound_shiftmax)
{
if (data != 0)
{
m_sound_shiftreg |= (data << (m_sound_shiftptr * 8));
m_sound_shiftptr++;
}
}
else
{
// doesn't happen
logerror("wiz_soundlatch_w overflow\n");
}
// d7: reset sound cpu?
if (data & 0x80)
{
m_sound_shiftreg = 0;
m_sound_shiftptr = 0;
m_sound_nmi_mask = 0;
m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
else
{
m_audiocpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
}
}
static ADDRESS_MAP_START( kungfut_main_map, AS_PROGRAM, 8, wiz_state )
AM_RANGE(0x0000, 0xbfff) AM_ROM AM_RANGE(0x0000, 0xbfff) AM_ROM
AM_RANGE(0xc000, 0xc7ff) AM_RAM AM_RANGE(0xc000, 0xc7ff) AM_RAM
AM_RANGE(0xc800, 0xc801) AM_WRITE(wiz_coin_counter_w) AM_RANGE(0xd000, 0xd3ff) AM_RAM AM_SHARE("videoram2")
AM_RANGE(0xd000, 0xd3ff) AM_SHARE("videoram2") /* Fallthrough */ AM_RANGE(0xd400, 0xd7ff) AM_RAM AM_SHARE("colorram2")
AM_RANGE(0xd400, 0xd7ff) AM_SHARE("colorram2") AM_RANGE(0xd800, 0xd83f) AM_RAM AM_SHARE("attrram2")
AM_RANGE(0xd800, 0xd83f) AM_SHARE("attributesram2") AM_RANGE(0xd840, 0xd85f) AM_RAM AM_SHARE("spriteram2")
AM_RANGE(0xd840, 0xd85f) AM_SHARE("spriteram2") AM_RANGE(0xe000, 0xe3ff) AM_RAM AM_SHARE("videoram")
AM_RANGE(0xd000, 0xd85f) AM_RAM AM_RANGE(0xe400, 0xe7ff) AM_RAM AM_SHARE("colorram")
AM_RANGE(0xe000, 0xe3ff) AM_SHARE("videoram") /* Fallthrough */ AM_RANGE(0xe800, 0xe83f) AM_RAM AM_SHARE("attrram")
AM_RANGE(0xe400, 0xe7ff) AM_RAM AM_RANGE(0xe840, 0xe85f) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0xe800, 0xe83f) AM_SHARE("attributesram")
AM_RANGE(0xe840, 0xe85f) AM_SHARE("spriteram")
AM_RANGE(0xe000, 0xe85f) AM_RAM
AM_RANGE(0xf000, 0xf000) AM_READ_PORT("DSW0") AM_RANGE(0xf000, 0xf000) AM_READ_PORT("DSW0")
AM_RANGE(0xf000, 0xf000) AM_RAM AM_SHARE("sprite_bank")
AM_RANGE(0xf001, 0xf001) AM_WRITE(wiz_main_nmi_mask_w) AM_RANGE(0xf001, 0xf001) AM_WRITE(wiz_main_nmi_mask_w)
AM_RANGE(0xf002, 0xf003) AM_WRITE(wiz_palettebank_w) AM_RANGE(0xf002, 0xf003) AM_WRITE(wiz_palette_bank_w)
AM_RANGE(0xf004, 0xf005) AM_WRITE(wiz_char_bank_select_w) AM_RANGE(0xf004, 0xf005) AM_WRITE(wiz_char_bank_w)
AM_RANGE(0xf006, 0xf006) AM_WRITE(wiz_flipx_w) AM_RANGE(0xf006, 0xf006) AM_WRITE(wiz_flipx_w)
AM_RANGE(0xf007, 0xf007) AM_WRITE(wiz_flipy_w) AM_RANGE(0xf007, 0xf007) AM_WRITE(wiz_flipy_w)
AM_RANGE(0xf008, 0xf008) AM_READ_PORT("DSW1") AM_RANGE(0xf008, 0xf008) AM_READ_PORT("DSW1")
AM_RANGE(0xf008, 0xf00f) AM_WRITENOP /* initialized by Stinger/Scion */
AM_RANGE(0xf010, 0xf010) AM_READ_PORT("IN0") AM_RANGE(0xf010, 0xf010) AM_READ_PORT("IN0")
AM_RANGE(0xf018, 0xf018) AM_READ_PORT("IN1") AM_RANGE(0xf018, 0xf018) AM_READ_PORT("IN1")
AM_RANGE(0xf800, 0xf800) AM_READ(watchdog_reset_r) AM_RANGE(0xf800, 0xf800) AM_WRITE(wiz_soundlatch_w)
AM_RANGE(0xf800, 0xf80f) AM_WRITE(sound_command_w) /* sound registers */
AM_RANGE(0xf818, 0xf818) AM_WRITE(wiz_bgcolor_w) AM_RANGE(0xf818, 0xf818) AM_WRITE(wiz_bgcolor_w)
ADDRESS_MAP_END ADDRESS_MAP_END
static ADDRESS_MAP_START( wiz_main_map, AS_PROGRAM, 8, wiz_state )
AM_RANGE(0xc800, 0xc801) AM_WRITE(wiz_coin_counter_w)
AM_RANGE(0xd400, 0xd400) AM_READ(wiz_protection_r)
AM_RANGE(0xf000, 0xf000) AM_WRITE(wiz_sprite_bank_w)
AM_IMPORT_FROM( kungfut_main_map )
ADDRESS_MAP_END
static ADDRESS_MAP_START( stinger_main_map, AS_PROGRAM, 8, wiz_state )
// AM_RANGE(0xf008, 0xf00f) AM_WRITENOP // ?
AM_RANGE(0xf800, 0xf800) AM_READ(watchdog_reset_r)
AM_RANGE(0xf808, 0xf808) AM_WRITE(stinger_explosion_w)
AM_RANGE(0xf80a, 0xf80a) AM_WRITE(stinger_shot_w)
AM_IMPORT_FROM( kungfut_main_map )
ADDRESS_MAP_END
/**************************************************************************/
WRITE8_MEMBER(wiz_state::wiz_sound_nmi_mask_w) WRITE8_MEMBER(wiz_state::wiz_sound_nmi_mask_w)
{ {
m_sound_nmi_mask = data & 1; m_sound_nmi_mask = data & 1;
} }
READ8_MEMBER(wiz_state::wiz_soundlatch_r)
{
// shift out soundlatch
UINT8 ret = m_sound_shiftreg & 0xff;
m_sound_shiftreg >>= 8;
m_sound_shiftptr -= (m_sound_shiftptr != 0);
return ret;
}
/* TODO: clean this up! */
static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, wiz_state )
AM_RANGE(0x0000, 0x1fff) AM_ROM
AM_RANGE(0x2000, 0x23ff) AM_RAM
AM_RANGE(0x3000, 0x3000) AM_READ(soundlatch_byte_r) AM_WRITE(wiz_sound_nmi_mask_w) /* Stinger/Scion */
AM_RANGE(0x4000, 0x4001) AM_DEVWRITE("8910.3", ay8910_device, address_data_w)
AM_RANGE(0x5000, 0x5001) AM_DEVWRITE("8910.1", ay8910_device, address_data_w)
AM_RANGE(0x6000, 0x6001) AM_DEVWRITE("8910.2", ay8910_device, address_data_w) /* Wiz only */
AM_RANGE(0x7000, 0x7000) AM_READ(soundlatch_byte_r) AM_WRITE(wiz_sound_nmi_mask_w) /* Wiz */
ADDRESS_MAP_END
static ADDRESS_MAP_START( stinger_sound_map, AS_PROGRAM, 8, wiz_state ) static ADDRESS_MAP_START( stinger_sound_map, AS_PROGRAM, 8, wiz_state )
AM_RANGE(0x0000, 0x1fff) AM_ROM AM_RANGE(0x0000, 0x1fff) AM_ROM
AM_RANGE(0x2000, 0x23ff) AM_RAM AM_RANGE(0x2000, 0x23ff) AM_RAM
AM_RANGE(0x3000, 0x3000) AM_READ(soundlatch_byte_r) AM_WRITE(wiz_sound_nmi_mask_w) /* Stinger/Scion */ AM_RANGE(0x3000, 0x3000) AM_READWRITE(wiz_soundlatch_r, wiz_sound_nmi_mask_w) AM_MIRROR(0x4000)
AM_RANGE(0x5000, 0x5001) AM_DEVWRITE("8910.1", ay8910_device, address_data_w) AM_RANGE(0x5000, 0x5001) AM_DEVWRITE("8910.1", ay8910_device, address_data_w)
AM_RANGE(0x6000, 0x6001) AM_DEVWRITE("8910.2", ay8910_device, address_data_w) /* Wiz only */ AM_RANGE(0x6000, 0x6001) AM_DEVWRITE("8910.2", ay8910_device, address_data_w)
AM_RANGE(0x7000, 0x7000) AM_READ(soundlatch_byte_r) AM_WRITE(wiz_sound_nmi_mask_w) /* Wiz */ ADDRESS_MAP_END
static ADDRESS_MAP_START( kungfut_sound_map, AS_PROGRAM, 8, wiz_state )
AM_RANGE(0x4000, 0x4001) AM_DEVWRITE("8910.3", ay8910_device, address_data_w) // one more ay8910
AM_IMPORT_FROM( stinger_sound_map )
ADDRESS_MAP_END ADDRESS_MAP_END
/***************************************************************************
Inputs
***************************************************************************/
static INPUT_PORTS_START( stinger ) static INPUT_PORTS_START( stinger )
PORT_START("IN0") PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
@ -287,14 +421,14 @@ static INPUT_PORTS_START( stinger )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
PORT_START("IN1") PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL
PORT_START("DSW0") PORT_START("DSW0")
PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_A ) ) PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_A ) )
@ -375,10 +509,10 @@ static INPUT_PORTS_START( scion )
PORT_INCLUDE( stinger ) PORT_INCLUDE( stinger )
PORT_MODIFY("IN1") PORT_MODIFY("IN1")
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL
PORT_MODIFY("DSW0") PORT_MODIFY("DSW0")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Cabinet ) ) PORT_DIPNAME( 0x01, 0x01, DEF_STR( Cabinet ) )
@ -434,19 +568,19 @@ static INPUT_PORTS_START( kungfut )
PORT_START("IN0") PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START2 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_START1 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_START("IN1") PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(1) PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(1) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_2WAY PORT_PLAYER(2)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME ("Microphone Input") PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME ("Microphone Input") // call up cloud
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN ) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2) PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_2WAY PORT_PLAYER(2)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
@ -501,7 +635,6 @@ static INPUT_PORTS_START( kungfut )
PORT_DIPSETTING( 0x80, DEF_STR( On ) ) PORT_DIPSETTING( 0x80, DEF_STR( On ) )
INPUT_PORTS_END INPUT_PORTS_END
/* Are button 1 & 2 actually inverted? */
static INPUT_PORTS_START( wiz ) static INPUT_PORTS_START( wiz )
PORT_START("IN0") PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
@ -514,14 +647,14 @@ static INPUT_PORTS_START( wiz )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_COCKTAIL // Magic PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_COCKTAIL // Magic
PORT_START("IN1") PORT_START("IN1")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_COCKTAIL
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_COCKTAIL
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_COCKTAIL
PORT_START("DSW0") PORT_START("DSW0")
PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coin_A ) ) PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coin_A ) )
@ -572,6 +705,12 @@ INPUT_PORTS_END
/***************************************************************************
Machine configs, misc. interface
***************************************************************************/
static const gfx_layout charlayout = static const gfx_layout charlayout =
{ {
8,8, /* 8*8 characters */ 8,8, /* 8*8 characters */
@ -583,7 +722,6 @@ static const gfx_layout charlayout =
8*8 /* every char takes 8 consecutive bytes */ 8*8 /* every char takes 8 consecutive bytes */
}; };
static const gfx_layout spritelayout = static const gfx_layout spritelayout =
{ {
16,16, /* 16*16 sprites */ 16,16, /* 16*16 sprites */
@ -619,83 +757,46 @@ static GFXDECODE_START( stinger )
GFXDECODE_ENTRY( "gfx2", 0x0000, spritelayout, 0, 32 ) GFXDECODE_ENTRY( "gfx2", 0x0000, spritelayout, 0, 32 )
GFXDECODE_END GFXDECODE_END
/**************************************************************************/
//* ANALOG SOUND STARTS
// cut-and-pasted from Asteroid
static const discrete_lfsr_desc stinger_lfsr =
{
DISC_CLK_IS_FREQ,
16, /* Bit Length */
0, /* Reset Value */
6, /* Use Bit 6 as XOR input 0 */
14, /* Use Bit 14 as XOR input 1 */
DISC_LFSR_XNOR, /* Feedback stage1 is XNOR */
DISC_LFSR_OR, /* Feedback stage2 is just stage 1 output OR with external feed */
DISC_LFSR_REPLACE, /* Feedback stage3 replaces the shifted register contents */
0x000001, /* Everything is shifted into the first bit only */
0, /* Output is already inverted by XNOR */
16 /* Output bit is feedback bit */
};
static DISCRETE_SOUND_START(stinger)
#define STINGER_SHOT_OUT NODE_90
#define STINGER_BOOM_OUT NODE_91
#define STINGER_FINAL_MIX NODE_99
// triggers are interleaved to give each circuit sufficient time to reset
DISCRETE_INPUT_LOGIC (STINGER_SHOT_EN1) // even-inteval shots
DISCRETE_INPUT_LOGIC (STINGER_SHOT_EN2) // odd-inteval shots
DISCRETE_INPUT_LOGIC (STINGER_BOOM_EN1) // even-inteval explosions
DISCRETE_INPUT_LOGIC (STINGER_BOOM_EN2) // odd-inteval explosions
//---------------------------------------
// Sample Shot Sound Circuit
#define SHOT_IN1 NODE_11
#define SHOT_IN2 NODE_12
#define SHOT_MOD NODE_13
#define SHOT_FRQ NODE_14
#define SHOT_AMP NODE_15
DISCRETE_RCDISC (SHOT_IN1, STINGER_SHOT_EN1, 1.0, 0.2, 1.0)
DISCRETE_RCDISC (SHOT_IN2, STINGER_SHOT_EN2, 1.0, 0.2, 1.0)
DISCRETE_SWITCH (SHOT_MOD, 1, STINGER_SHOT_EN1, SHOT_IN2, SHOT_IN1)
DISCRETE_MULTIPLY (SHOT_FRQ, SHOT_MOD, 2000)
DISCRETE_MULTIPLY (SHOT_AMP, SHOT_MOD, 800)
DISCRETE_SQUAREWAVE (STINGER_SHOT_OUT, 1, SHOT_FRQ, SHOT_AMP, 50, 0, 0)
//---------------------------------------
// Sample Explosion Sound Circuit
#define BOOM_IN1 NODE_21
#define BOOM_IN2 NODE_22
#define BOOM_MOD NODE_23
#define BOOM_AMP NODE_24
DISCRETE_RCDISC (BOOM_IN1, STINGER_BOOM_EN1, 1.0, 0.25, 1.0)
DISCRETE_RCDISC (BOOM_IN2, STINGER_BOOM_EN2, 1.0, 0.25, 1.0)
DISCRETE_SWITCH (BOOM_MOD, 1, STINGER_BOOM_EN1, BOOM_IN2, BOOM_IN1)
DISCRETE_MULTIPLY (BOOM_AMP, BOOM_MOD, 1500)
DISCRETE_LFSR_NOISE (STINGER_BOOM_OUT, 1, 1, 1800, BOOM_AMP, 0, 0, &stinger_lfsr)
//---------------------------------------
DISCRETE_ADDER2 (STINGER_FINAL_MIX, 1, STINGER_SHOT_OUT, STINGER_BOOM_OUT)
DISCRETE_OUTPUT (STINGER_FINAL_MIX, 5)
DISCRETE_SOUND_END
//* ANALOG SOUND ENDS
void wiz_state::machine_reset() void wiz_state::machine_reset()
{ {
m_dsc0 = m_dsc1 = 1; m_dsc0 = m_dsc1 = 1;
m_main_nmi_mask = 0;
m_sound_shiftreg = 0;
m_sound_shiftptr = 0;
m_sound_nmi_mask = 0;
m_sprite_bank = 0;
m_charbank[0] = m_charbank[1] = 0;
m_palbank[0] = m_palbank[1] = 0;
m_flipx = 0;
m_flipy = 0;
m_bgcolor = 0;
} }
void wiz_state::machine_start()
{
// register for savestates
save_item(NAME(m_dsc0));
save_item(NAME(m_dsc1));
save_item(NAME(m_main_nmi_mask));
save_item(NAME(m_sound_shiftreg));
save_item(NAME(m_sound_shiftptr));
save_item(NAME(m_sound_nmi_mask));
save_item(NAME(m_sprite_bank));
save_item(NAME(m_charbank));
save_item(NAME(m_palbank));
save_item(NAME(m_flipx));
save_item(NAME(m_flipy));
save_item(NAME(m_bgcolor));
}
/**************************************************************************/
INTERRUPT_GEN_MEMBER(wiz_state::wiz_vblank_interrupt) INTERRUPT_GEN_MEMBER(wiz_state::wiz_vblank_interrupt)
{ {
if (m_main_nmi_mask & 1) if (m_main_nmi_mask & 1)
@ -708,32 +809,31 @@ INTERRUPT_GEN_MEMBER(wiz_state::wiz_sound_interrupt)
device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
} }
static MACHINE_CONFIG_START( kungfut, wiz_state )
static MACHINE_CONFIG_START( wiz, wiz_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z80, 18432000/6) /* 3.072 MHz ??? */ MCFG_CPU_ADD("maincpu", Z80, 18432000/6) /* 3.072 MHz ??? */
MCFG_CPU_PROGRAM_MAP(main_map) MCFG_CPU_PROGRAM_MAP(kungfut_main_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", wiz_state, wiz_vblank_interrupt) MCFG_CPU_VBLANK_INT_DRIVER("screen", wiz_state, wiz_vblank_interrupt)
MCFG_CPU_ADD("audiocpu", Z80, 14318000/8) /* ? */ MCFG_CPU_ADD("audiocpu", Z80, 18432000/6) /* 3.072 MHz ??? */
MCFG_CPU_PROGRAM_MAP(sound_map) MCFG_CPU_PROGRAM_MAP(kungfut_sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(wiz_state, wiz_sound_interrupt, 4*60) /* ??? */ MCFG_CPU_PERIODIC_INT_DRIVER(wiz_state, wiz_sound_interrupt, 4*60) /* ??? */
MCFG_QUANTUM_TIME(attotime::from_hz(60000))
/* video hardware */ /* video hardware */
MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */ /* frames per second, vblank duration */) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */ )
MCFG_SCREEN_SIZE(32*8, 32*8) MCFG_SCREEN_SIZE(32*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1)
MCFG_SCREEN_UPDATE_DRIVER(wiz_state, screen_update_wiz) MCFG_SCREEN_UPDATE_DRIVER(wiz_state, screen_update_kungfut)
MCFG_GFXDECODE_ADD("gfxdecode", wiz) MCFG_GFXDECODE_ADD("gfxdecode", stinger)
MCFG_PALETTE_ADD("palette", 256) MCFG_PALETTE_ADD("palette", 256)
MCFG_PALETTE_INIT_OWNER(wiz_state, wiz) MCFG_PALETTE_INIT_OWNER(wiz_state, wiz)
/* sound hardware */ /* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SPEAKER_STANDARD_MONO("mono")
@ -747,16 +847,30 @@ static MACHINE_CONFIG_START( wiz, wiz_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.10) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.10)
MACHINE_CONFIG_END MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( wiz, kungfut )
static MACHINE_CONFIG_DERIVED( stinger, wiz )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(wiz_main_map)
/* video hardware */
MCFG_GFXDECODE_MODIFY("gfxdecode", wiz)
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_UPDATE_DRIVER(wiz_state, screen_update_wiz)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( stinger, kungfut )
/* basic machine hardware */
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(stinger_main_map)
/* basic machine hardware */
MCFG_CPU_MODIFY("audiocpu") MCFG_CPU_MODIFY("audiocpu")
MCFG_CPU_PROGRAM_MAP(stinger_sound_map) MCFG_CPU_PROGRAM_MAP(stinger_sound_map)
/* video hardware */ /* video hardware */
MCFG_GFXDECODE_MODIFY("gfxdecode", stinger)
MCFG_SCREEN_MODIFY("screen") MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_UPDATE_DRIVER(wiz_state, screen_update_stinger) MCFG_SCREEN_UPDATE_DRIVER(wiz_state, screen_update_stinger)
@ -768,27 +882,11 @@ static MACHINE_CONFIG_DERIVED( stinger, wiz )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
MACHINE_CONFIG_END MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( scion, stinger ) static MACHINE_CONFIG_DERIVED( scion, stinger )
/* basic machine hardware */
/* video hardware */ /* video hardware */
MCFG_SCREEN_MODIFY("screen") MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_VISIBLE_AREA(2*8, 32*8-1, 2*8, 30*8-1) MCFG_SCREEN_VISIBLE_AREA(2*8, 32*8-1, 2*8, 30*8-1)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( kungfut, wiz )
/* basic machine hardware */
/* video hardware */
MCFG_GFXDECODE_MODIFY("gfxdecode", stinger)
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_UPDATE_DRIVER(wiz_state, screen_update_kungfut)
MACHINE_CONFIG_END MACHINE_CONFIG_END
@ -817,6 +915,7 @@ ROM_START( kungfut )
ROM_LOAD( "5.bin", 0x0000, 0x2000, CRC(763bb61a) SHA1(9bea4a929db5d2e8c925a847591b9e5b2ad5aaaa) ) ROM_LOAD( "5.bin", 0x0000, 0x2000, CRC(763bb61a) SHA1(9bea4a929db5d2e8c925a847591b9e5b2ad5aaaa) )
ROM_LOAD( "6.bin", 0x2000, 0x2000, CRC(c9649fce) SHA1(f65e75355d2f7b0899ea3769146a55b187da37d3) ) ROM_LOAD( "6.bin", 0x2000, 0x2000, CRC(c9649fce) SHA1(f65e75355d2f7b0899ea3769146a55b187da37d3) )
ROM_LOAD( "7.bin", 0x4000, 0x2000, CRC(32f02c13) SHA1(85781f03cca622ce8ee66924a1e72758ce42bdfe) ) ROM_LOAD( "7.bin", 0x4000, 0x2000, CRC(32f02c13) SHA1(85781f03cca622ce8ee66924a1e72758ce42bdfe) )
ROM_REGION( 0x0300, "proms", 0 ) ROM_REGION( 0x0300, "proms", 0 )
ROM_LOAD( "82s129.0", 0x0000, 0x0100, CRC(eb823177) SHA1(a28233dbf87744a9896fe675b76603557e7f596b) ) ROM_LOAD( "82s129.0", 0x0000, 0x0100, CRC(eb823177) SHA1(a28233dbf87744a9896fe675b76603557e7f596b) )
ROM_LOAD( "82s129.1", 0x0100, 0x0100, CRC(6eec5dd9) SHA1(e846209c167b2a7d790faacea082a7edc1338e47) ) ROM_LOAD( "82s129.1", 0x0100, 0x0100, CRC(6eec5dd9) SHA1(e846209c167b2a7d790faacea082a7edc1338e47) )
@ -1042,7 +1141,6 @@ ROM_START( scionc )
ROM_END ROM_END
DRIVER_INIT_MEMBER(wiz_state,stinger) DRIVER_INIT_MEMBER(wiz_state,stinger)
{ {
static const UINT8 swap_xor_table[4][4] = static const UINT8 swap_xor_table[4][4] =
@ -1056,55 +1154,41 @@ DRIVER_INIT_MEMBER(wiz_state,stinger)
UINT8 *rom = memregion("maincpu")->base(); UINT8 *rom = memregion("maincpu")->base();
int size = memregion("maincpu")->bytes(); int size = memregion("maincpu")->bytes();
UINT8 *decrypt = auto_alloc_array(machine(), UINT8, size); UINT8 *decrypt = auto_alloc_array(machine(), UINT8, size);
int A;
const UINT8 *tbl; const UINT8 *tbl;
space.set_decrypted_region(0x0000, 0xffff, decrypt); space.set_decrypted_region(0x0000, 0xffff, decrypt);
for (A = 0x0000;A < 0x10000;A++) for (int a = 0x0000; a < 0x10000; a++)
{ {
int row; int row;
UINT8 src; UINT8 src;
if (a & 0x2040)
if (A & 0x2040)
{ {
/* not encrypted */ /* not encrypted */
decrypt[A] = rom[A]; decrypt[a] = rom[a];
} }
else else
{ {
src = rom[A]; src = rom[a];
/* pick the translation table from bits 3 and 5 of the address */ /* pick the translation table from bits 3 and 5 of the address */
row = ((A >> 3) & 1) + (((A >> 5) & 1) << 1); row = ((a >> 3) & 1) + (((a >> 5) & 1) << 1);
/* decode the opcodes */ /* decode the opcodes */
tbl = swap_xor_table[row]; tbl = swap_xor_table[row];
decrypt[A] = BITSWAP8(src,tbl[0],6,tbl[1],4,tbl[2],2,1,0) ^ tbl[3]; decrypt[a] = BITSWAP8(src, tbl[0], 6, tbl[1], 4, tbl[2], 2, 1, 0) ^ tbl[3];
} }
} }
} }
DRIVER_INIT_MEMBER(wiz_state,scion) GAME( 1983, stinger, 0, stinger, stinger, wiz_state, stinger, ROT90, "Seibu Denshi", "Stinger", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_COLORS )
{ GAME( 1983, stinger2, stinger, stinger, stinger2, wiz_state, stinger, ROT90, "Seibu Denshi", "Stinger (prototype?)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_COLORS )
m_audiocpu->space(AS_PROGRAM).nop_write(0x4000, 0x4001); GAME( 1984, scion, 0, scion, scion, driver_device, 0, ROT0, "Seibu Denshi", "Scion", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_COLORS )
} GAME( 1984, scionc, scion, scion, scion, driver_device, 0, ROT0, "Seibu Denshi (Cinematronics license)", "Scion (Cinematronics)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_COLORS )
DRIVER_INIT_MEMBER(wiz_state,wiz)
{
m_maincpu->space(AS_PROGRAM).install_read_handler(0xd400, 0xd400, read8_delegate(FUNC(wiz_state::wiz_protection_r),this));
}
GAME( 1983, stinger, 0, stinger, stinger, wiz_state, stinger, ROT90, "Seibu Denshi", "Stinger", GAME_IMPERFECT_SOUND )
GAME( 1983, stinger2, stinger, stinger, stinger2, wiz_state, stinger, ROT90, "Seibu Denshi", "Stinger (prototype?)", GAME_IMPERFECT_SOUND )
GAME( 1984, scion, 0, scion, scion, wiz_state, scion, ROT0, "Seibu Denshi", "Scion", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_COLORS )
GAME( 1984, scionc, scion, scion, scion, wiz_state, scion, ROT0, "Seibu Denshi (Cinematronics license)", "Scion (Cinematronics)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_COLORS )
GAME( 1984, kungfut, 0, kungfut, kungfut, driver_device, 0, ROT0, "Seibu Kaihatsu", "Kung-Fu Taikun (set 1)", 0 ) GAME( 1984, kungfut, 0, kungfut, kungfut, driver_device, 0, ROT0, "Seibu Kaihatsu", "Kung-Fu Taikun (set 1)", 0 )
GAME( 1984, kungfuta, kungfut, kungfut, kungfut, driver_device, 0, ROT0, "Seibu Kaihatsu", "Kung-Fu Taikun (set 2)", 0 ) /* board was a bootleg but set might still be original */ GAME( 1984, kungfuta, kungfut, kungfut, kungfut, driver_device, 0, ROT0, "Seibu Kaihatsu", "Kung-Fu Taikun (set 2)", 0 ) /* board was a bootleg but set might still be original */
GAME( 1985, wiz, 0, wiz, wiz, wiz_state, wiz, ROT270, "Seibu Kaihatsu", "Wiz", 0 ) GAME( 1985, wiz, 0, wiz, wiz, driver_device, 0, ROT270, "Seibu Kaihatsu", "Wiz", 0 )
GAME( 1985, wizt, wiz, wiz, wiz, wiz_state, wiz, ROT270, "Seibu Kaihatsu (Taito license)", "Wiz (Taito, set 1)", 0 ) GAME( 1985, wizt, wiz, wiz, wiz, driver_device, 0, ROT270, "Seibu Kaihatsu (Taito license)", "Wiz (Taito, set 1)", 0 )
GAME( 1985, wizta, wiz, wiz, wiz, wiz_state, wiz, ROT270, "Seibu Kaihatsu (Taito license)", "Wiz (Taito, set 2)", 0 ) GAME( 1985, wizta, wiz, wiz, wiz, driver_device, 0, ROT270, "Seibu Kaihatsu (Taito license)", "Wiz (Taito, set 2)", 0 )

View File

@ -1,71 +1,88 @@
/***************************************************************************
Seibu Stinger/Wiz hardware
***************************************************************************/
#include "sound/discrete.h" #include "sound/discrete.h"
#include "sound/ay8910.h"
class wiz_state : public driver_device class wiz_state : public driver_device
{ {
public: public:
wiz_state(const machine_config &mconfig, device_type type, const char *tag) wiz_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag),
m_videoram2(*this, "videoram2"),
m_colorram2(*this, "colorram2"),
m_attributesram2(*this, "attributesram2"),
m_spriteram2(*this, "spriteram2"),
m_videoram(*this, "videoram"),
m_attributesram(*this, "attributesram"),
m_spriteram(*this, "spriteram"),
m_sprite_bank(*this, "sprite_bank"),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"), m_audiocpu(*this, "audiocpu"),
m_discrete(*this, "discrete"), m_discrete(*this, "discrete"),
m_gfxdecode(*this, "gfxdecode"), m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette") { } m_palette(*this, "palette"),
m_videoram(*this, "videoram"),
m_videoram2(*this, "videoram2"),
m_colorram(*this, "colorram"),
m_colorram2(*this, "colorram2"),
m_attrram(*this, "attrram"),
m_attrram2(*this, "attrram2"),
m_spriteram(*this, "spriteram"),
m_spriteram2(*this, "spriteram2")
{ }
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<discrete_device> m_discrete;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
int m_dsc0;
int m_dsc1;
required_shared_ptr<UINT8> m_videoram2;
required_shared_ptr<UINT8> m_colorram2;
required_shared_ptr<UINT8> m_attributesram2;
required_shared_ptr<UINT8> m_spriteram2;
required_shared_ptr<UINT8> m_videoram; required_shared_ptr<UINT8> m_videoram;
required_shared_ptr<UINT8> m_attributesram; required_shared_ptr<UINT8> m_videoram2;
required_shared_ptr<UINT8> m_colorram;
required_shared_ptr<UINT8> m_colorram2;
required_shared_ptr<UINT8> m_attrram;
required_shared_ptr<UINT8> m_attrram2;
required_shared_ptr<UINT8> m_spriteram; required_shared_ptr<UINT8> m_spriteram;
required_shared_ptr<UINT8> m_sprite_bank; required_shared_ptr<UINT8> m_spriteram2;
INT32 m_flipx; INT32 m_flipx;
INT32 m_flipy; INT32 m_flipy;
INT32 m_bgpen; INT32 m_bgcolor;
UINT8 m_char_bank[2]; UINT8 m_charbank[2];
UINT8 m_palbank[2]; UINT8 m_palbank[2];
int m_palette_bank;
UINT8 m_main_nmi_mask; UINT8 m_main_nmi_mask;
UINT8 m_sound_nmi_mask; UINT8 m_sound_nmi_mask;
UINT8 m_sprite_bank;
DECLARE_WRITE8_MEMBER(sound_command_w); UINT64 m_sound_shiftreg; // unknown size, this should be more than enough
static const int m_sound_shiftmax = 8;
UINT8 m_sound_shiftptr;
int m_dsc0;
int m_dsc1;
DECLARE_WRITE8_MEMBER(wiz_soundlatch_w);
DECLARE_READ8_MEMBER(wiz_protection_r); DECLARE_READ8_MEMBER(wiz_protection_r);
DECLARE_WRITE8_MEMBER(wiz_coin_counter_w); DECLARE_WRITE8_MEMBER(wiz_coin_counter_w);
DECLARE_WRITE8_MEMBER(wiz_main_nmi_mask_w); DECLARE_WRITE8_MEMBER(wiz_main_nmi_mask_w);
DECLARE_WRITE8_MEMBER(wiz_sound_nmi_mask_w); DECLARE_WRITE8_MEMBER(wiz_sound_nmi_mask_w);
DECLARE_WRITE8_MEMBER(wiz_palettebank_w); DECLARE_WRITE8_MEMBER(wiz_palette_bank_w);
DECLARE_WRITE8_MEMBER(wiz_sprite_bank_w);
DECLARE_WRITE8_MEMBER(wiz_bgcolor_w); DECLARE_WRITE8_MEMBER(wiz_bgcolor_w);
DECLARE_WRITE8_MEMBER(wiz_char_bank_select_w); DECLARE_WRITE8_MEMBER(wiz_char_bank_w);
DECLARE_WRITE8_MEMBER(wiz_flipx_w); DECLARE_WRITE8_MEMBER(wiz_flipx_w);
DECLARE_WRITE8_MEMBER(wiz_flipy_w); DECLARE_WRITE8_MEMBER(wiz_flipy_w);
DECLARE_DRIVER_INIT(wiz); DECLARE_READ8_MEMBER(wiz_soundlatch_r);
DECLARE_DRIVER_INIT(scion); DECLARE_WRITE8_MEMBER(stinger_explosion_w);
DECLARE_WRITE8_MEMBER(stinger_shot_w);
DECLARE_DRIVER_INIT(stinger); DECLARE_DRIVER_INIT(stinger);
virtual void machine_reset(); virtual void machine_reset();
virtual void video_start(); virtual void machine_start();
DECLARE_PALETTE_INIT(wiz); DECLARE_PALETTE_INIT(wiz);
UINT32 screen_update_wiz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); UINT32 screen_update_wiz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update_stinger(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); UINT32 screen_update_stinger(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT32 screen_update_kungfut(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); UINT32 screen_update_kungfut(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(wiz_vblank_interrupt); INTERRUPT_GEN_MEMBER(wiz_vblank_interrupt);
INTERRUPT_GEN_MEMBER(wiz_sound_interrupt); INTERRUPT_GEN_MEMBER(wiz_sound_interrupt);
void draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect, int bank, int colortype); void draw_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int charbank, int colortype);
void draw_foreground(bitmap_ind16 &bitmap, const rectangle &cliprect, int colortype); void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int set, int charbank);
void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect, UINT8* sprite_ram,int bank);
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<discrete_device> m_discrete;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
}; };

View File

@ -1,24 +1,16 @@
/*************************************************************************** /***************************************************************************
video.c Seibu Stinger/Wiz hardware
Functions to emulate the video hardware of the machine. Functions to emulate the video hardware of the machine.
***************************************************************************/ ***************************************************************************/
#include "emu.h" #include "emu.h"
#include "video/resnet.h"
#include "includes/wiz.h" #include "includes/wiz.h"
void wiz_state::video_start()
{
save_item(NAME(m_char_bank));
save_item(NAME(m_palbank));
save_item(NAME(m_flipx));
save_item(NAME(m_flipy));
save_item(NAME(m_bgpen));
}
/*************************************************************************** /***************************************************************************
Convert the color PROMs into a more useable format. Convert the color PROMs into a more useable format.
@ -32,206 +24,198 @@ void wiz_state::video_start()
bit 0 -- 1 kohm resistor -- RED/GREEN/BLUE bit 0 -- 1 kohm resistor -- RED/GREEN/BLUE
***************************************************************************/ ***************************************************************************/
PALETTE_INIT_MEMBER(wiz_state, wiz) PALETTE_INIT_MEMBER(wiz_state, wiz)
{ {
const UINT8 *color_prom = memregion("proms")->base(); const UINT8 *color_prom = memregion("proms")->base();
int i; static const int resistances[4] = { 1000, 470, 220, 100 };
double rweights[4], gweights[4], bweights[4];
/* compute the color output resistor weights */
compute_resistor_weights(0, 255, -1.0,
4, resistances, rweights, 470, 0,
4, resistances, gweights, 470, 0,
4, resistances, bweights, 470, 0);
for (i = 0;i < palette.entries();i++) /* initialize the palette with these colors */
for (int i = 0; i < 0x100; i++)
{ {
int bit0,bit1,bit2,bit3,r,g,b; int bit0, bit1, bit2, bit3;
int r, g, b;
/* red component */
bit0 = (color_prom[i + 0x000] >> 0) & 0x01;
bit1 = (color_prom[i + 0x000] >> 1) & 0x01;
bit2 = (color_prom[i + 0x000] >> 2) & 0x01;
bit3 = (color_prom[i + 0x000] >> 3) & 0x01;
r = combine_4_weights(rweights, bit0, bit1, bit2, bit3);
bit0 = (color_prom[0] >> 0) & 0x01; /* green component */
bit1 = (color_prom[0] >> 1) & 0x01; bit0 = (color_prom[i + 0x100] >> 0) & 0x01;
bit2 = (color_prom[0] >> 2) & 0x01; bit1 = (color_prom[i + 0x100] >> 1) & 0x01;
bit3 = (color_prom[0] >> 3) & 0x01; bit2 = (color_prom[i + 0x100] >> 2) & 0x01;
r = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3; bit3 = (color_prom[i + 0x100] >> 3) & 0x01;
bit0 = (color_prom[palette.entries()] >> 0) & 0x01; g = combine_4_weights(gweights, bit0, bit1, bit2, bit3);
bit1 = (color_prom[palette.entries()] >> 1) & 0x01;
bit2 = (color_prom[palette.entries()] >> 2) & 0x01;
bit3 = (color_prom[palette.entries()] >> 3) & 0x01;
g = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
bit0 = (color_prom[2*palette.entries()] >> 0) & 0x01;
bit1 = (color_prom[2*palette.entries()] >> 1) & 0x01;
bit2 = (color_prom[2*palette.entries()] >> 2) & 0x01;
bit3 = (color_prom[2*palette.entries()] >> 3) & 0x01;
b = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
palette.set_pen_color(i,rgb_t(r,g,b)); /* blue component */
bit0 = (color_prom[i + 0x200] >> 0) & 0x01;
bit1 = (color_prom[i + 0x200] >> 1) & 0x01;
bit2 = (color_prom[i + 0x200] >> 2) & 0x01;
bit3 = (color_prom[i + 0x200] >> 3) & 0x01;
b = combine_4_weights(bweights, bit0, bit1, bit2, bit3);
color_prom++; m_palette->set_pen_color(i, rgb_t(r, g, b));
} }
} }
WRITE8_MEMBER(wiz_state::wiz_palettebank_w)
/***************************************************************************
I/O
***************************************************************************/
WRITE8_MEMBER(wiz_state::wiz_palette_bank_w)
{ {
m_palbank[offset] = data & 1; m_palbank[offset] = data & 1;
m_palette_bank = m_palbank[0] + 2 * m_palbank[1]; }
WRITE8_MEMBER(wiz_state::wiz_char_bank_w)
{
m_charbank[offset] = data & 1;
}
WRITE8_MEMBER(wiz_state::wiz_sprite_bank_w)
{
m_sprite_bank = data & 1;
} }
WRITE8_MEMBER(wiz_state::wiz_bgcolor_w) WRITE8_MEMBER(wiz_state::wiz_bgcolor_w)
{ {
m_bgpen = data; m_bgcolor = data;
}
WRITE8_MEMBER(wiz_state::wiz_char_bank_select_w)
{
m_char_bank[offset] = data & 1;
} }
WRITE8_MEMBER(wiz_state::wiz_flipx_w) WRITE8_MEMBER(wiz_state::wiz_flipx_w)
{ {
m_flipx = data; m_flipx = data & 1;
} }
WRITE8_MEMBER(wiz_state::wiz_flipy_w) WRITE8_MEMBER(wiz_state::wiz_flipy_w)
{ {
m_flipy = data; m_flipy = data & 1;
} }
void wiz_state::draw_background(bitmap_ind16 &bitmap, const rectangle &cliprect, int bank, int colortype)
/***************************************************************************
Screen Update
***************************************************************************/
void wiz_state::draw_tiles(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int charbank, int colortype)
{ {
UINT8 *videoram = m_videoram; UINT8 *vram = layer ? m_videoram2 : m_videoram;
int offs; UINT8 *aram = layer ? m_attrram2 : m_attrram;
UINT8 *cram = layer ? m_colorram2 : m_colorram;
gfx_element *gfx = m_gfxdecode->gfx(charbank);
int palbank = m_palbank[1] << 4 | m_palbank[0] << 3;
/* for every character in the Video RAM, check if it has been modified */ /* draw the tiles. They are characters, but draw them as sprites. */
/* since last time and update it accordingly. */ for (int offs = 0x400-1; offs >= 0; offs--)
for (offs = 0x400 - 1; offs >= 0; offs--)
{ {
int scroll,sx,sy,col; int scroll;
sx = offs % 32; int code = vram[offs];
sy = offs / 32; int sx = offs & 0x1f;
int sy = offs >> 5;
int color = aram[sx << 1 | 1] & 7;
if (colortype) if (colortype)
{ color = layer ? (cram[offs] & 7) : ((color & 4) | (vram[offs] & 3));
col = (m_attributesram[2 * sx + 1] & 0x07);
}
else
{
col = (m_attributesram[2 * (offs % 32) + 1] & 0x04) + (videoram[offs] & 3);
}
scroll = (8*sy + 256 - m_attributesram[2 * sx]) % 256; scroll = (8*sy + 256 - aram[2 * sx]) & 0xff;
if (m_flipy) if (m_flipy)
{ {
scroll = (248 - scroll) % 256; scroll = (248 - scroll) & 0xff;
} }
if (m_flipx) sx = 31 - sx; if (m_flipx) sx = 31 - sx;
gfx->transpen(m_palette,bitmap,cliprect,
m_gfxdecode->gfx(bank)->transpen(m_palette,bitmap,cliprect, code,
videoram[offs], palbank | color,
col + 8 * m_palette_bank,
m_flipx,m_flipy, m_flipx,m_flipy,
8*sx,scroll,0); 8*sx,scroll,0);
} }
} }
void wiz_state::draw_foreground(bitmap_ind16 &bitmap, const rectangle &cliprect, int colortype)
void wiz_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect, int set, int charbank)
{ {
int offs; UINT8 *sram = set ? m_spriteram2 : m_spriteram;
gfx_element *gfx = m_gfxdecode->gfx(charbank);
int palbank = m_palbank[1] << 4 | m_palbank[0] << 3;
/* draw the frontmost playfield. They are characters, but draw them as sprites. */ for (int offs = 0x20-4; offs >= 0; offs -= 4)
for (offs = 0x400 - 1; offs >= 0; offs--)
{ {
int scroll,sx,sy,col; int code = sram[offs + 1];
int sx = sram[offs + 3];
int sy = sram[offs];
sx = offs % 32; int color = sram[offs + 2] & 7; // high bits unused
sy = offs / 32;
if (colortype)
{
col = (m_attributesram2[2 * sx + 1] & 0x07);
}
else
{
col = (m_colorram2[offs] & 0x07);
}
scroll = (8*sy + 256 - m_attributesram2[2 * sx]) % 256;
if (m_flipy)
{
scroll = (248 - scroll) % 256;
}
if (m_flipx) sx = 31 - sx;
m_gfxdecode->gfx(m_char_bank[1])->transpen(m_palette,bitmap,cliprect,
m_videoram2[offs],
col + 8 * m_palette_bank,
m_flipx,m_flipy,
8*sx,scroll,0);
}
}
void wiz_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect, UINT8* sprite_ram,int bank)
{
int offs;
for (offs = m_spriteram.bytes() - 4;offs >= 0;offs -= 4)
{
int sx,sy;
sx = sprite_ram[offs + 3];
sy = sprite_ram[offs];
if (!sx || !sy) continue; if (!sx || !sy) continue;
// like on galaxian hw, the first three sprites match against y-1 (not on m_spriteram2)
if (set == 0 && offs <= 8)
sy += (m_flipy) ? 1 : -1;
if ( m_flipx) sx = 240 - sx; if ( m_flipx) sx = 240 - sx;
if (!m_flipy) sy = 240 - sy; if (!m_flipy) sy = 240 - sy;
m_gfxdecode->gfx(bank)->transpen(m_palette,bitmap,cliprect, gfx->transpen(m_palette,bitmap,cliprect,
sprite_ram[offs + 1], code,
(sprite_ram[offs + 2] & 0x07) + 8 * m_palette_bank, palbank | color,
m_flipx,m_flipy, m_flipx,m_flipy,
sx,sy,0); sx,sy,0);
} }
} }
/**************************************************************************/
UINT32 wiz_state::screen_update_kungfut(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) UINT32 wiz_state::screen_update_kungfut(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
bitmap.fill(m_bgpen, cliprect); bitmap.fill(m_bgcolor, cliprect);
draw_background(bitmap, cliprect, 2 + m_char_bank[0] , 0); draw_tiles(bitmap, cliprect, 0, 2 + m_charbank[0], 1);
draw_foreground(bitmap, cliprect, 0); draw_tiles(bitmap, cliprect, 1, m_charbank[1], 1);
draw_sprites(bitmap, cliprect, m_spriteram2, 4); draw_sprites(bitmap, cliprect, 1, 4);
draw_sprites(bitmap, cliprect, m_spriteram , 5); draw_sprites(bitmap, cliprect, 0, 5);
return 0; return 0;
} }
UINT32 wiz_state::screen_update_wiz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) UINT32 wiz_state::screen_update_wiz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
int bank; bitmap.fill(m_bgcolor, cliprect);
draw_tiles(bitmap, cliprect, 0, 2 + ((m_charbank[0] << 1) | m_charbank[1]), 1);
bitmap.fill(m_bgpen, cliprect); draw_tiles(bitmap, cliprect, 1, m_charbank[1], 1);
draw_background(bitmap, cliprect, 2 + ((m_char_bank[0] << 1) | m_char_bank[1]), 0);
draw_foreground(bitmap, cliprect, 0);
const rectangle spritevisiblearea(2*8, 32*8-1, 2*8, 30*8-1); const rectangle spritevisiblearea(2*8, 32*8-1, 2*8, 30*8-1);
const rectangle spritevisibleareaflipx(0*8, 30*8-1, 2*8, 30*8-1); const rectangle spritevisibleareaflipx(0*8, 30*8-1, 2*8, 30*8-1);
const rectangle &visible_area = m_flipx ? spritevisibleareaflipx : spritevisiblearea; const rectangle &visible_area = m_flipx ? spritevisibleareaflipx : spritevisiblearea;
bank = 7 + *m_sprite_bank; draw_sprites(bitmap, visible_area, 1, 6);
draw_sprites(bitmap, visible_area, 0, 7 + m_sprite_bank);
draw_sprites(bitmap, visible_area, m_spriteram2, 6);
draw_sprites(bitmap, visible_area, m_spriteram , bank);
return 0; return 0;
} }
UINT32 wiz_state::screen_update_stinger(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) UINT32 wiz_state::screen_update_stinger(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
bitmap.fill(m_bgpen, cliprect); bitmap.fill(m_bgcolor, cliprect);
draw_background(bitmap, cliprect, 2 + m_char_bank[0], 1); draw_tiles(bitmap, cliprect, 0, 2 + m_charbank[0], 0);
draw_foreground(bitmap, cliprect, 1); draw_tiles(bitmap, cliprect, 1, m_charbank[1], 0);
draw_sprites(bitmap, cliprect, m_spriteram2, 4); draw_sprites(bitmap, cliprect, 1, 4);
draw_sprites(bitmap, cliprect, m_spriteram , 5); draw_sprites(bitmap, cliprect, 0, 5);
return 0; return 0;
} }