Cleaned up Crazy Baloon driver: proper memory maps, crystals, etc.

Implemented the missing features of the collision detector custom IC, this fixes long standing bug crbaloon36finalgre
This commit is contained in:
Zsolt Vasvari 2008-01-15 11:28:14 +00:00
parent a3f186b44b
commit 4d5bee4733
4 changed files with 477 additions and 350 deletions

View File

@ -1,24 +1,76 @@
/***************************************************************************
Taito Crazy Balloon hardware
Analog emulation - Jan 2006, Derrick Renaud
***************************************************************************/
#include "driver.h"
#include "crbaloon.h"
#include "sound/sn76477.h"
#include "sound/discrete.h"
/************************************************************************
* crbaloon Sound System Analog emulation
* Jan 2006, Derrick Renaud
************************************************************************/
/* timing sources */
#define CRBALOON_16H (CRBALOON_MASTER_XTAL/2/2/16)
/* enables */
#define CRBALOON_LAUGH_EN NODE_01
#define CRBALOON_MUSIC_EN NODE_02
#define CRBALOON_MUSIC_DATA NODE_03
/* Timing Sources */
#define CRBALOON_16H 9987000.0/2/2/16
/* Nodes - Adjusters */
/* nodes - adjusters */
#define CRBALOON_VR2 NODE_05
#define CRBALOON_VR3 NODE_06
/* Nodes - Sounds */
/* nodes - sounds */
#define CRBALOON_LAUGH_SND NODE_80
#define CRBALOON_MUSIC_SND NODE_81
void crbaloon_audio_set_music_freq(UINT8 freq)
{
discrete_sound_w(CRBALOON_MUSIC_DATA, freq);
}
void crbaloon_audio_set_music_enable(int enabled)
{
discrete_sound_w(CRBALOON_MUSIC_EN, enabled);
}
void crbaloon_audio_set_explosion_enable(int enabled)
{
SN76477_enable_w(0, enabled);
}
void crbaloon_audio_set_breath_enable(int enabled)
{
/* changes slf_res to 10k (middle of two 10k resistors)
it also puts a tantal capacitor against GND on the output,
but this section of the schematics is not readable. */
SN76477_slf_res_w(0, enabled ? RES_K(10) : RES_K(20) );
}
void crbaloon_audio_set_appear_enable(int enabled)
{
/* APPEAR is connected to MIXER B */
SN76477_mixer_b_w(0, enabled);
}
void crbaloon_audio_set_laugh_enable(int enabled)
{
discrete_sound_w(CRBALOON_LAUGH_EN, enabled);
}
static const discrete_555_desc desc_crbaloon_laugh_osc =
{
DISC_555_OUT_SQW | DISC_555_OUT_DC,
@ -26,6 +78,7 @@ static const discrete_555_desc desc_crbaloon_laugh_osc =
DEFAULT_555_VALUES
};
static const discrete_dac_r1_ladder desc_crbaloon_music_dac =
{
3,
@ -33,7 +86,9 @@ static const discrete_dac_r1_ladder desc_crbaloon_music_dac =
5, RES_K(470), 0, 0
};
DISCRETE_SOUND_START(crbaloon)
static DISCRETE_SOUND_START(crbaloon)
/************************************************
* Input register mapping
@ -78,3 +133,47 @@ DISCRETE_SOUND_START(crbaloon)
DISCRETE_OUTPUT(NODE_91, 65000.0/12)
DISCRETE_SOUND_END
static const struct SN76477interface sn76477_interface =
{
RES_K( 47), /* 4 noise_res */
RES_K(330), /* 5 filter_res */
CAP_P(470), /* 6 filter_cap */
RES_K(220), /* 7 decay_res */
CAP_U(1.0), /* 8 attack_decay_cap */
RES_K(4.7), /* 10 attack_res */
RES_M( 1), /* 11 amplitude_res */
RES_K(200), /* 12 feedback_res */
5.0, /* 16 vco_voltage */
CAP_P(470), /* 17 vco_cap */
RES_K(330), /* 18 vco_res */
5.0, /* 19 pitch_voltage */
RES_K( 20), /* 20 slf_res (variable) */
CAP_P(420), /* 21 slf_cap */
CAP_U(1.0), /* 23 oneshot_cap */
RES_K( 47), /* 24 oneshot_res */
0, /* 22 vco */
0, /* 26 mixer A */
0, /* 25 mixer B (variable) */
1, /* 27 mixer C */
1, /* 1 envelope 1 */
0, /* 28 envelope 2 */
0 /* 9 enable (variable) */
};
MACHINE_DRIVER_START( crbaloon_audio )
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD(SN76477, 0)
MDRV_SOUND_CONFIG(sn76477_interface)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 2.0)
MDRV_SOUND_ADD_TAG("discrete", DISCRETE, 0)
MDRV_SOUND_CONFIG_DISCRETE(crbaloon)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_DRIVER_END

View File

@ -1,220 +1,266 @@
/***************************************************************************
Crazy Balloon memory map (preliminary)
Taito Crazy Balloon hardware
0000-2fff ROM
4000-43ff RAM
4800-4bff Video RAM
5000-53ff Color RAM
Copyright Nicola Salmoria and the MAME Team.
I/O:
read:
00 dsw
01 joystick
02 bit 0-3 from chip PC3259 (bit 3 is the sprite/char collision detection)
bit 4-7 dsw
03 bit 0 dsw
bit 1 high score name reset
bit 2 service
bit 3 tilt
bit 4-7 from chip PC3092; coin inputs & start buttons
06-0a-0e mirror addresses for 02; address lines 2 and 3 go to the PC3256 chip
so they probably alter its output, while the dsw bits (4-7) stay the same.
write:
01 ?
02 bit 0-3 sprite code bit 4-7 sprite color
03 sprite X pos
04 sprite Y pos
05 music?? to a counter?
06 sound
bit 0 IRQ enable/acknowledge
bit 1 sound enable
bit 2 sound related (to amplifier)
bit 3 explosion (to 76477)
bit 4 breath (to 76477)
bit 5 appear (to 76477)
bit 6 sound related (to 555)
bit 7 to chip PC3259
07 to chip PC3092 (bits 0-3)
08 to chip PC3092 (bits 0-3)
bit 0 seems to be flip screen
bit 1 might enable coin input
09 to chip PC3092 (bits 0-3)
0a to chip PC3092 (bits 0-3)
0b to chip PC3092 (bits 0-3)
0c MSK (to chip PC3259)
0d CC (not used)
To-Do:
* Video timing from schematics
* Watchdog length from schematics
* Interrupt timing from schematics
* DIP switches
* Faithfully implement the custom chips
* Coin counter and lock-out
***************************************************************************/
#include "driver.h"
#include "sound/sn76477.h"
#include "sound/custom.h"
#include "crbaloon.h"
static UINT8 *pc3092_data;
static UINT8 val06,val08,val0a;
static MACHINE_START( crbaloon )
/*************************************
*
* PC3092 custom chip
*
* Inputs: pins 1-4 - D0-D3 of data bus
* pin 5 - 1P ENTRY (start button 1)
* pin 6 - 2P ENTRY (start button 2)
* pin 7 - COIN
* pin 8 - /4HN (pixel timing)
* pin 9 - port 0x0a written to
* pin 10 - port 0x08 written to
* pin 11 - port 0x07 written to
* pin 13 - /RESET
* pin 14 - port 0x09 written to
* pin 15 - port 0x0b written to
*
* Outputs: pins 16-19 - D28-D31 of I/O bus
* pin 20 - /V-INV (flip screen)
* pin 21 - coin counter
*
*************************************/
#define LOG_PC3092 0
static void pc3092_reset(void)
{
state_save_register_global(val06);
state_save_register_global(val08);
state_save_register_global(val0a);
/* nothing yet */
}
static WRITE8_HANDLER( crbaloon_06_w )
static void pc3092_update(void)
{
val06 = data;
interrupt_enable_w(offset,data & 1);
/* SOUND STOP is really sound enable */
sound_global_enable(data & 0x02);
/* enable is connected to EXPLOSION */
SN76477_enable_w(0, (data & 0x08) ? 1 : 0);
/* BREATH changes slf_res to 10k (middle of two 10k resistors) */
/* it also puts a tantal capacitor against GND on the output,
but this section of the schematics is not readable. */
SN76477_slf_res_w(0, (data & 0x10) ? RES_K(10) : RES_K(20) );
/* APPEAR is connected to MIXER B */
SN76477_mixer_b_w(0, (data & 0x20) ? 1 : 0);
discrete_sound_w(CRBALOON_MUSIC_EN, data & 0x04);
discrete_sound_w(CRBALOON_LAUGH_EN, data & 0x40);
flip_screen_set((pc3092_data[1] & 0x01) ? TRUE : FALSE);
}
static WRITE8_HANDLER( crbaloon_08_w )
{
val08 = data;
crbaloon_flipscreen_w(offset,data & 1);
static WRITE8_HANDLER( pc3092_w )
{
pc3092_data[offset] = data & 0x0f;
if (LOG_PC3092) logerror("%04X: write PC3092 #%d = 0x%02x\n", safe_activecpu_get_pc(), offset, pc3092_data[offset]);
pc3092_update();
}
static WRITE8_HANDLER( crbaloon_0a_w )
{
val0a = data;
}
static READ8_HANDLER( crbaloon_IN2_r )
static UINT32 pc3092_r(void *param)
{
if (crbaloon_collision != 0)
{
return (input_port_2_r(0) & 0xf0) | 0x08;
}
UINT32 ret;
/* the following is needed for the game to boot up */
if (val06 & 0x80)
{
logerror("PC %04x: %02x high\n",activecpu_get_pc(),offset);
return (input_port_2_r(0) & 0xf0) | 0x07;
}
/* enable coin & start input? Wild guess!!! */
if (pc3092_data[1] & 0x02)
ret = readinputportbytag("PC3092");
else
{
logerror("PC %04x: %02x low\n",activecpu_get_pc(),offset);
return (input_port_2_r(0) & 0xf0) | 0x07;
}
ret = 0x00;
if (LOG_PC3092) logerror("%04X: read PC3092 = 0x%02x\n", safe_activecpu_get_pc(), ret);
return ret;
}
static READ8_HANDLER( crbaloon_IN3_r )
/*************************************
*
* PC3259 custom chip -
* collision detection
*
* Inputs: pins 1-10 - 128V/64V/32V/16V/8V
* 128H/64H/32H/16H/8H
* video timing lines
* pin 11 - CLK
* pin 13 - /HTCLR
* pin 14 - MVID
* pin 15 - T1
* pin 16 - D7 of SOUND port buffer
* pin 21/22 - AD2/AD3 of address bus
* pin 23 - MSK (port 0x0c written to)
*
* Outputs: pins 17-20 - D24-D27 of I/O bus
*
*************************************/
#define LOG_PC3259 0
static void pc3259_update(void)
{
if (val08 & 0x02)
/* enable coin & start input? Wild guess!!! */
return input_port_3_r(0);
/* the following is needed for the game to boot up */
if (val0a & 0x01)
{
logerror("PC %04x: 03 high\n",activecpu_get_pc());
return (input_port_3_r(0) & 0x0f) | 0x00;
}
else
{
logerror("PC %04x: 03 low\n",activecpu_get_pc());
return (input_port_3_r(0) & 0x0f) | 0x00;
}
/* nothing yet */
}
static READ8_HANDLER( crbaloon_IN_r )
static READ8_HANDLER( pc3259_r )
{
switch (offset & 0x03)
UINT8 ret = 0;
UINT8 reg = offset >> 2;
UINT16 collision_address = crbaloon_get_collision_address();
int collided = (collision_address != 0xffff);
switch (reg)
{
case 0:
return input_port_0_r(offset);
case 0x00:
ret = collided ? (collision_address & 0x0f) : 0;
break;
case 1:
return input_port_1_r(offset);
case 0x01:
ret = collided ? ((collision_address >> 4) & 0x0f) : 0;
break;
case 2:
return crbaloon_IN2_r(offset);
case 0x02:;
ret = collided ? (collision_address >> 8) : 0;
break;
case 3:
return crbaloon_IN3_r(offset);
default:
case 0x03:
ret = collided ? 0x08 : 0x07;
break;
}
return 0;
if (LOG_PC3259) logerror("%04X: read PC3259 #%d = 0x%02x\n", safe_activecpu_get_pc(), reg, ret);
return ret | (readinputportbytag("DSW1") & 0xf0);
}
static WRITE8_HANDLER( crbaloon_tone_w )
/*************************************
*
* I/O ports
*
*************************************/
static WRITE8_HANDLER( port_sound_w )
{
discrete_sound_w(CRBALOON_MUSIC_DATA, data);
/* D0 - interrupt enable - also goes to PC3259 as /HTCTRL */
cpu_interrupt_enable(0, (data & 0x01) ? TRUE : FALSE);
crbaloon_set_clear_collision_address((data & 0x01) ? TRUE : FALSE);
/* D1 - SOUND STOP */
sound_global_enable((data & 0x02) ? TRUE : FALSE);
/* D2 - unlabeled - music enable */
crbaloon_audio_set_music_enable((data & 0x04) ? TRUE : FALSE);
/* D3 - EXPLOSION */
crbaloon_audio_set_explosion_enable((data & 0x08) ? TRUE : FALSE);
/* D4 - BREATH */
crbaloon_audio_set_breath_enable((data & 0x10) ? TRUE : FALSE);
/* D5 - APPEAR */
crbaloon_audio_set_appear_enable((data & 0x20) ? TRUE : FALSE);
/* D6 - unlabeled - laugh enable */
crbaloon_audio_set_laugh_enable((data & 0x40) ? TRUE : FALSE);
/* D7 - unlabeled - goes to PC3259 pin 16 */
pc3259_update();
}
static WRITE8_HANDLER( port_music_w )
{
crbaloon_audio_set_music_freq(data);
}
static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x2fff) AM_READ(MRA8_ROM)
AM_RANGE(0x4000, 0x43ff) AM_READ(MRA8_RAM)
AM_RANGE(0x4800, 0x4bff) AM_READ(MRA8_RAM)
AM_RANGE(0x5000, 0x53ff) AM_READ(MRA8_RAM)
ADDRESS_MAP_END
/*************************************
*
* Memory handlers
*
*************************************/
static ADDRESS_MAP_START( writemem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x2fff) AM_WRITE(MWA8_ROM)
AM_RANGE(0x4000, 0x43ff) AM_WRITE(MWA8_RAM)
AM_RANGE(0x4800, 0x4bff) AM_WRITE(crbaloon_videoram_w) AM_BASE(&videoram)
AM_RANGE(0x5000, 0x53ff) AM_WRITE(crbaloon_colorram_w) AM_BASE(&colorram)
ADDRESS_MAP_END
static ADDRESS_MAP_START( readport, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_FLAGS( AMEF_ABITS(8) )
AM_RANGE(0x00, 0x0f) AM_READ(crbaloon_IN_r)
ADDRESS_MAP_END
static ADDRESS_MAP_START( writeport, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_FLAGS( AMEF_ABITS(8) )
AM_RANGE(0x02, 0x04) AM_WRITE(crbaloon_spritectrl_w)
AM_RANGE(0x05, 0x05) AM_WRITE(crbaloon_tone_w)
AM_RANGE(0x06, 0x06) AM_WRITE(crbaloon_06_w)
AM_RANGE(0x08, 0x08) AM_WRITE(crbaloon_08_w)
AM_RANGE(0x0a, 0x0a) AM_WRITE(crbaloon_0a_w)
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 )
ADDRESS_MAP_FLAGS( AMEF_ABITS(15) ) /* A15 is not decoded */
AM_RANGE(0x0000, 0x3fff) AM_ROM /* not fully populated */
AM_RANGE(0x4000, 0x43ff) AM_MIRROR(0x0400) AM_RAM
AM_RANGE(0x4800, 0x4bff) AM_MIRROR(0x0400) AM_READWRITE(MRA8_RAM, crbaloon_videoram_w) AM_BASE(&crbaloon_videoram)
AM_RANGE(0x5000, 0x53ff) AM_MIRROR(0x0400) AM_READWRITE(MRA8_RAM, crbaloon_colorram_w) AM_BASE(&crbaloon_colorram)
AM_RANGE(0x5800, 0x7fff) AM_NOP
ADDRESS_MAP_END
/*************************************
*
* Port handlers
*
*************************************/
static ADDRESS_MAP_START( main_io_map, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_FLAGS( AMEF_ABITS(4) )
AM_RANGE(0x00, 0x00) AM_MIRROR(0x0c) AM_READ(port_tag_to_handler8("DSW0"))
AM_RANGE(0x01, 0x01) AM_MIRROR(0x0c) AM_READ(port_tag_to_handler8("IN0"))
/* AM_SPACE(0x02, 0x03) AM_READ(pc3259_r) crashes if not at the end */
AM_RANGE(0x03, 0x03) AM_MIRROR(0x0c) AM_READ(port_tag_to_handler8("IN1"))
AM_RANGE(0x00, 0x00) AM_WRITE(MWA8_NOP) /* not connected */
AM_RANGE(0x01, 0x01) AM_WRITE(MWA8_NOP) /* watchdog */
AM_RANGE(0x02, 0x04) AM_WRITE(MWA8_RAM) AM_BASE(&crbaloon_spriteram)
AM_RANGE(0x05, 0x05) AM_WRITE(port_music_w)
AM_RANGE(0x06, 0x06) AM_WRITE(port_sound_w)
AM_RANGE(0x07, 0x0b) AM_WRITE(pc3092_w) AM_BASE(&pc3092_data)
AM_RANGE(0x0c, 0x0c) AM_WRITE(MWA8_NOP) /* MSK - to PC3259 */
AM_RANGE(0x0d, 0x0d) AM_WRITE(MWA8_NOP) /* schematics has it in a box marked "NOT USE" */
AM_RANGE(0x0e, 0x0f) AM_WRITE(MWA8_NOP)
AM_SPACE(0x02, 0x03) AM_READ(pc3259_r)
ADDRESS_MAP_END
/*************************************
*
* Port definition
*
*************************************/
static INPUT_PORTS_START( crbaloon )
PORT_START_TAG("DSW0") // 0
PORT_DIPNAME( 0x01, 0x01, "Test?" )
PORT_START_TAG("DSW0")
PORT_DIPNAME( 0x01, 0x01, "Test?" ) PORT_DIPLOCATION("SW A:1")
PORT_DIPSETTING( 0x01, "I/O Check?" )
PORT_DIPSETTING( 0x00, "RAM Check?" )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Cabinet ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW A:2")
PORT_DIPSETTING( 0x02, DEF_STR( Upright ) )
PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
PORT_DIPNAME( 0x0c, 0x04, DEF_STR( Lives ) )
PORT_DIPNAME( 0x0c, 0x04, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW A:3,4")
PORT_DIPSETTING( 0x00, "2" )
PORT_DIPSETTING( 0x04, "3" )
PORT_DIPSETTING( 0x08, "4" )
PORT_DIPSETTING( 0x0c, "5" )
PORT_DIPNAME( 0x10, 0x00, DEF_STR( Bonus_Life ) )
PORT_DIPNAME( 0x10, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW A:5")
PORT_DIPSETTING( 0x00, "5000" )
PORT_DIPSETTING( 0x10, "10000" )
PORT_DIPNAME( 0xe0, 0x80, DEF_STR( Coinage ) )
PORT_DIPNAME( 0xe0, 0x80, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW A:6,7,8")
PORT_DIPSETTING( 0x20, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x40, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x60, DEF_STR( 2C_1C ) )
@ -224,7 +270,7 @@ static INPUT_PORTS_START( crbaloon )
PORT_DIPSETTING( 0xe0, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x00, "Disable" )
PORT_START_TAG("IN0") // 1
PORT_START_TAG("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
@ -234,38 +280,40 @@ static INPUT_PORTS_START( crbaloon )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
PORT_START_TAG("DSW1") // 2
PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* from chip PC3259 */
PORT_DIPNAME( 0x10, 0x10, "Invulnerability (Cheat)")
PORT_START_TAG("DSW1")
PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_SPECIAL ) /* PC3259 */
PORT_DIPNAME( 0x10, 0x10, "Invulnerability") PORT_DIPLOCATION("SW B:1")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW B:2")
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW B:3")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW B:4")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START_TAG("IN1") // 3
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
PORT_START_TAG("IN1")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW B:5")
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("High Score Name Reset")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) /* should be COIN2 */
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Name Reset")
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_TILT )
/* the following four bits come from chip PC3092 */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(pc3092_r, 0)
PORT_START_TAG("VR2") // 4
PORT_START_TAG("PC3092")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START_TAG("VR2")
PORT_ADJUSTER(50, "VR2 - Beep")
PORT_START_TAG("VR3") // 5
PORT_START_TAG("VR3")
PORT_ADJUSTER(50, "VR3 - Music")
INPUT_PORTS_END
@ -282,103 +330,73 @@ static const gfx_layout charlayout =
{ 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
8*8 /* every char takes 8 consecutive bytes */
};
static const gfx_layout spritelayout =
{
32,32, /* 32*32 sprites */
16, /* 16 sprites */
1, /* 1 bit per pixel */
{ 0 },
{ 3*32*8+0, 3*32*8+1, 3*32*8+2, 3*32*8+3, 3*32*8+4, 3*32*8+5, 3*32*8+6, 3*32*8+7,
2*32*8+0, 2*32*8+1, 2*32*8+2, 2*32*8+3, 2*32*8+4, 2*32*8+5, 2*32*8+6, 2*32*8+7,
1*32*8+0, 1*32*8+1, 1*32*8+2, 1*32*8+3, 1*32*8+4, 1*32*8+5, 1*32*8+6, 1*32*8+7,
0*32*8+0, 0*32*8+1, 0*32*8+2, 0*32*8+3, 0*32*8+4, 0*32*8+5, 0*32*8+6, 0*32*8+7 },
{ 31*8, 30*8, 29*8, 28*8, 27*8, 26*8, 25*8, 24*8,
23*8, 22*8, 21*8, 20*8, 19*8, 18*8, 17*8, 16*8,
15*8, 14*8, 13*8, 12*8, 11*8, 10*8, 9*8, 8*8,
7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
32*4*8 /* every sprite takes 128 consecutive bytes */
};
static GFXDECODE_START( crbaloon )
GFXDECODE_ENTRY( REGION_GFX1, 0, charlayout, 0, 16 )
GFXDECODE_ENTRY( REGION_GFX2, 0, spritelayout, 0, 16 )
GFXDECODE_ENTRY( REGION_GFX1, 0, charlayout, 0, 16 )
GFXDECODE_END
static const struct SN76477interface sn76477_interface =
{
RES_K( 47), /* 4 noise_res */
RES_K(330), /* 5 filter_res */
CAP_P(470), /* 6 filter_cap */
RES_K(220), /* 7 decay_res */
CAP_U(1.0), /* 8 attack_decay_cap */
RES_K(4.7), /* 10 attack_res */
RES_M( 1), /* 11 amplitude_res */
RES_K(200), /* 12 feedback_res */
5.0, /* 16 vco_voltage */
CAP_P(470), /* 17 vco_cap */
RES_K(330), /* 18 vco_res */
5.0, /* 19 pitch_voltage */
RES_K( 20), /* 20 slf_res (variable) */
CAP_P(420), /* 21 slf_cap */
CAP_U(1.0), /* 23 oneshot_cap */
RES_K( 47), /* 24 oneshot_res */
0, /* 22 vco */
0, /* 26 mixer A */
0, /* 25 mixer B (variable) */
1, /* 27 mixer C */
1, /* 1 envelope 1 */
0, /* 28 envelope 2 */
0 /* 9 enable (variable) */
};
/*************************************
*
* Machine reset
*
*************************************/
MACHINE_RESET( crballoon )
{
pc3092_reset();
port_sound_w(0, 0);
port_music_w(0, 0);
}
/*************************************
*
* Machine driver
*
*************************************/
static MACHINE_DRIVER_START( crbaloon )
/* basic machine hardware */
MDRV_CPU_ADD(Z80, 3072000) /* 3.072 MHz ????? */
MDRV_CPU_PROGRAM_MAP(readmem,writemem)
MDRV_CPU_IO_MAP(readport,writeport)
MDRV_CPU_ADD(Z80, CRBALOON_MASTER_XTAL / 3)
MDRV_CPU_PROGRAM_MAP(main_map,0)
MDRV_CPU_IO_MAP(main_io_map,0)
MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
MDRV_MACHINE_START(crbaloon)
MDRV_MACHINE_RESET(crballoon)
/* video hardware */
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_SCREEN_SIZE(32*8, 32*8)
MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
MDRV_GFXDECODE(crbaloon)
MDRV_PALETTE_LENGTH(16)
MDRV_COLORTABLE_LENGTH(16*2)
MDRV_PALETTE_INIT(crbaloon)
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER | VIDEO_ALWAYS_UPDATE)
MDRV_VIDEO_START(crbaloon)
MDRV_VIDEO_UPDATE(crbaloon)
/* sound hardware */
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_GFXDECODE(crbaloon)
MDRV_PALETTE_LENGTH(16)
MDRV_PALETTE_INIT(crbaloon)
MDRV_COLORTABLE_LENGTH(16*2)
MDRV_SOUND_ADD(SN76477, 0)
MDRV_SOUND_CONFIG(sn76477_interface)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 2.0)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_SCREEN_SIZE(32*8, 32*8)
MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
/* audio hardware */
MDRV_IMPORT_FROM(crbaloon_audio)
MDRV_SOUND_ADD_TAG("discrete", DISCRETE, 0)
MDRV_SOUND_CONFIG_DISCRETE(crbaloon)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_DRIVER_END
/***************************************************************************
Game driver(s)
***************************************************************************/
/*************************************
*
* ROM definitions
*
*************************************/
ROM_START( crbaloon )
ROM_REGION( 0x10000, REGION_CPU1, 0 )
@ -392,10 +410,11 @@ ROM_START( crbaloon )
ROM_REGION( 0x0800, REGION_GFX1, ROMREGION_DISPOSE )
ROM_LOAD( "cl07.bin", 0x0000, 0x0800, CRC(2c1fbea8) SHA1(41cf2aef74d56173057886512d989f6fa3682056) )
ROM_REGION( 0x0800, REGION_GFX2, ROMREGION_DISPOSE )
ROM_REGION( 0x0800, REGION_GFX2, 0 )
ROM_LOAD( "cl08.bin", 0x0000, 0x0800, CRC(ba898659) SHA1(4291059b113ff91896f1f61a4c14956716edfe1e) )
ROM_END
ROM_START( crbalon2 )
ROM_REGION( 0x10000, REGION_CPU1, 0 )
ROM_LOAD( "cl01.bin", 0x0000, 0x0800, CRC(9d4eef0b) SHA1(a8dd814ac2612073982123c91fa62deaf5bee242) )
@ -408,11 +427,17 @@ ROM_START( crbalon2 )
ROM_REGION( 0x0800, REGION_GFX1, ROMREGION_DISPOSE )
ROM_LOAD( "cl07.bin", 0x0000, 0x0800, CRC(2c1fbea8) SHA1(41cf2aef74d56173057886512d989f6fa3682056) )
ROM_REGION( 0x0800, REGION_GFX2, ROMREGION_DISPOSE )
ROM_REGION( 0x0800, REGION_GFX2, 0 )
ROM_LOAD( "cl08.bin", 0x0000, 0x0800, CRC(ba898659) SHA1(4291059b113ff91896f1f61a4c14956716edfe1e) )
ROM_END
/*************************************
*
* Game drivers
*
*************************************/
GAME( 1980, crbaloon, 0, crbaloon, crbaloon, 0, ROT90, "Taito Corporation", "Crazy Balloon (set 1)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
GAME( 1980, crbalon2, crbaloon, crbaloon, crbaloon, 0, ROT90, "Taito Corporation", "Crazy Balloon (set 2)", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )

View File

@ -4,27 +4,35 @@ Crazy Ballooon
*************************************************************************/
#include "sound/discrete.h"
#define CRBALOON_LAUGH_EN NODE_01
#define CRBALOON_MUSIC_EN NODE_02
#define CRBALOON_MUSIC_DATA NODE_03
#define CRBALOON_MASTER_XTAL (XTAL_9_987MHz)
/*----------- defined in audio/crbaloon.c -----------*/
DISCRETE_SOUND_EXTERN( crbaloon );
void crbaloon_audio_set_music_freq(UINT8 freq);
void crbaloon_audio_set_music_enable(int enabled);
void crbaloon_audio_set_explosion_enable(int enabled);
void crbaloon_audio_set_breath_enable(int enabled);
void crbaloon_audio_set_appear_enable(int enabled);
void crbaloon_audio_set_laugh_enable(int enabled);
MACHINE_DRIVER_EXTERN( crbaloon_audio );
/*----------- defined in video/crbaloon.c -----------*/
extern INT8 crbaloon_collision;
WRITE8_HANDLER( crbaloon_videoram_w );
WRITE8_HANDLER( crbaloon_colorram_w );
WRITE8_HANDLER( crbaloon_spritectrl_w );
WRITE8_HANDLER( crbaloon_flipscreen_w );
extern UINT8 *crbaloon_videoram;
extern UINT8 *crbaloon_colorram;
extern UINT8 *crbaloon_spriteram;
PALETTE_INIT( crbaloon );
VIDEO_START( crbaloon );
VIDEO_UPDATE( crbaloon );
WRITE8_HANDLER( crbaloon_videoram_w );
WRITE8_HANDLER( crbaloon_colorram_w );
UINT16 crbaloon_get_collision_address(void);
void crbaloon_set_clear_collision_address(int _crbaloon_collision_address_clear);

View File

@ -9,12 +9,16 @@
#include "driver.h"
#include "includes/crbaloon.h"
static UINT8 spritectrl[3];
INT8 crbaloon_collision;
UINT8 *crbaloon_videoram;
UINT8 *crbaloon_colorram;
UINT8 *crbaloon_spriteram;
static UINT16 crbaloon_collision_address;
static UINT8 crbaloon_collision_address_clear;
static tilemap *bg_tilemap;
/***************************************************************************
Convert the color PROMs into a more useable format.
@ -27,6 +31,7 @@ static tilemap *bg_tilemap;
bit 0 RED
***************************************************************************/
PALETTE_INIT( crbaloon )
{
int i;
@ -34,134 +39,124 @@ PALETTE_INIT( crbaloon )
#define COLOR(gfxn,offs) (colortable[machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
for (i = 0;i < machine->drv->total_colors;i++)
for (i = 0; i < machine->drv->total_colors; i++)
{
int intensity,r,g,b;
int h = (~i & 0x08) ? 0xff : 0x55;
int r = h * ((~i >> 0) & 1);
int g = h * ((~i >> 1) & 1);
int b = h * ((~i >> 2) & 1);
intensity = (~i & 0x08) ? 0xff : 0x55;
/* red component */
r = intensity * ((~i >> 0) & 1);
/* green component */
g = intensity * ((~i >> 1) & 1);
/* blue component */
b = intensity * ((~i >> 2) & 1);
palette_set_color(machine,i,MAKE_RGB(r,g,b));
palette_set_color(machine, i, MAKE_RGB(r, g, b));
}
for (i = 0;i < TOTAL_COLORS(0);i += 2)
for (i = 0; i < TOTAL_COLORS(0); i += 2)
{
COLOR(0,i) = 15; /* black background */
COLOR(0,i + 1) = i / 2; /* colored foreground */
COLOR(0, i + 0) = 0x0f; /* black background */
COLOR(0, i + 1) = i / 2; /* colored foreground */
}
}
WRITE8_HANDLER( crbaloon_videoram_w )
{
videoram[offset] = data;
crbaloon_videoram[offset] = data;
tilemap_mark_tile_dirty(bg_tilemap, offset);
}
WRITE8_HANDLER( crbaloon_colorram_w )
{
colorram[offset] = data;
crbaloon_colorram[offset] = data;
tilemap_mark_tile_dirty(bg_tilemap, offset);
}
WRITE8_HANDLER( crbaloon_spritectrl_w )
{
spritectrl[offset] = data;
}
WRITE8_HANDLER( crbaloon_flipscreen_w )
{
if (flip_screen != (data & 0x01))
{
flip_screen_set(data & 0x01);
tilemap_mark_all_tiles_dirty(ALL_TILEMAPS);
}
}
static TILE_GET_INFO( get_bg_tile_info )
{
int code = videoram[tile_index];
int color = colorram[tile_index] & 0x0f;
int code = crbaloon_videoram[tile_index];
int color = crbaloon_colorram[tile_index] & 0x0f;
SET_TILE_INFO(0, code, color, 0);
}
VIDEO_START( crbaloon )
{
bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows_flip_xy,
TILEMAP_TYPE_PEN, 8, 8, 32, 32);
bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows_flip_xy, TILEMAP_TYPE_PEN, 8, 8, 32, 32);
tmpbitmap = auto_bitmap_alloc(machine->screen[0].width,machine->screen[0].height,machine->screen[0].format);
state_save_register_global_array(spritectrl);
state_save_register_global(crbaloon_collision);
state_save_register_global(crbaloon_collision_address);
state_save_register_global(crbaloon_collision_address_clear);
}
static void draw_sprites(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
UINT16 crbaloon_get_collision_address(void)
{
int x,y;
return crbaloon_collision_address_clear ? 0xffff : crbaloon_collision_address;
}
/* Check Collision - Draw balloon in background colour, if no */
/* collision occured, bitmap will be same as tmpbitmap */
int bx = spritectrl[1];
int by = spritectrl[2] - 32;
void crbaloon_set_clear_collision_address(int _crbaloon_collision_address_clear)
{
crbaloon_collision_address_clear = !_crbaloon_collision_address_clear; /* active LO */
}
static void draw_sprite_and_check_collision(running_machine *machine, mame_bitmap *bitmap)
{
int y;
UINT8 code = crbaloon_spriteram[0] & 0x0f;
UINT8 color = crbaloon_spriteram[0] >> 4;
UINT8 sy = crbaloon_spriteram[2] - 32;
UINT8 *gfx = memory_region(REGION_GFX2) + (code << 7);
tilemap_draw(tmpbitmap, 0, bg_tilemap, 0, 0);
if (flip_screen)
sy += 32;
/* assume no collision */
crbaloon_collision_address = 0xffff;
for (y = 0x1f; y >= 0; y--)
{
by += 32;
}
int x;
UINT8 data = 0;
UINT8 sx = crbaloon_spriteram[1];
drawgfx(bitmap,machine->gfx[1],
spritectrl[0] & 0x0f,
15,
0,0,
bx,by,
cliprect,TRANSPARENCY_PEN,0);
for (x = 0x1f; x >= 0; x--)
{
int bit;
crbaloon_collision = 0;
if ((x & 0x07) == 0x07)
/* get next byte to draw, but no drawing in VBLANK */
data = (sy >= 0xe0) ? 0 : gfx[((x >> 3) << 5) | y];
for (x = bx; x < bx + machine->gfx[1]->width; x++)
{
for (y = by; y < by + machine->gfx[1]->height; y++)
{
if ((x < machine->screen[0].visarea.min_x) ||
(x > machine->screen[0].visarea.max_x) ||
(y < machine->screen[0].visarea.min_y) ||
(y > machine->screen[0].visarea.max_y))
bit = data & 0x80;
/* draw the current pixel, but check collision first */
if (bit)
{
continue;
if (*BITMAP_ADDR16(bitmap, sy, sx) != 0x0f)
/* compute the collision address -- the +1 is via observation
of the game code, probably wrong for cocktail mode */
crbaloon_collision_address = ((((sy ^ 0xff) >> 3) << 5) | ((sx ^ 0xff) >> 3)) + 1;
*BITMAP_ADDR16(bitmap, sy, sx) = color;
}
if (*BITMAP_ADDR16(bitmap, y, x) != *BITMAP_ADDR16(tmpbitmap, y, x))
{
crbaloon_collision = -1;
break;
}
sx = sx + 1;
data = data << 1;
}
sy = sy + 1;
}
/* actually draw the balloon */
drawgfx(bitmap,machine->gfx[1],
spritectrl[0] & 0x0f,
(spritectrl[0] & 0xf0) >> 4,
0,0,
bx,by,
cliprect,TRANSPARENCY_PEN,0);
}
VIDEO_UPDATE( crbaloon )
{
tilemap_draw(bitmap, cliprect, bg_tilemap, 0, 0);
draw_sprites(machine, bitmap, cliprect);
draw_sprite_and_check_collision(machine, bitmap);
return 0;
}