Rewrote sbrkout driver based on schematics:

* XTAL-based timing
 * Correct video timing
 * Full memory map
 * Correct memory usage ("zero page" RAM is shared with videoram)
 * Removed all input hacks
 * Fixed interrupt generation
 * Connected coin counters
 * Added save state support

Also fixed incorrect dependency in cdrom.c.
This commit is contained in:
Aaron Giles 2008-01-03 09:01:18 +00:00
parent 422ccce762
commit 415aebd2bd
8 changed files with 355 additions and 334 deletions

3
.gitattributes vendored
View File

@ -2247,7 +2247,6 @@ src/mame/includes/rampart.h svneol=native#text/plain
src/mame/includes/realbrk.h svneol=native#text/plain
src/mame/includes/relief.h svneol=native#text/plain
src/mame/includes/rescap.h svneol=native#text/plain
src/mame/includes/sbrkout.h svneol=native#text/plain
src/mame/includes/segag80r.h svneol=native#text/plain
src/mame/includes/segag80v.h svneol=native#text/plain
src/mame/includes/segas24.h svneol=native#text/plain
@ -2488,7 +2487,6 @@ src/mame/machine/rainbow.c svneol=native#text/plain
src/mame/machine/retofinv.c svneol=native#text/plain
src/mame/machine/s16fd.c svneol=native#text/plain
src/mame/machine/s24fd.c svneol=native#text/plain
src/mame/machine/sbrkout.c svneol=native#text/plain
src/mame/machine/scramble.c svneol=native#text/plain
src/mame/machine/scudsp.c svneol=native#text/plain
src/mame/machine/scudsp.h svneol=native#text/plain
@ -3030,7 +3028,6 @@ src/mame/video/runaway.c svneol=native#text/plain
src/mame/video/rungun.c svneol=native#text/plain
src/mame/video/sauro.c svneol=native#text/plain
src/mame/video/sbasketb.c svneol=native#text/plain
src/mame/video/sbrkout.c svneol=native#text/plain
src/mame/video/sbugger.c svneol=native#text/plain
src/mame/video/scotrsht.c svneol=native#text/plain
src/mame/video/sderby.c svneol=native#text/plain

View File

@ -58,6 +58,7 @@ enum
XTAL_11MHz = 11000000, /* Mario I8039 sound */
XTAL_11_289MHz = 11289000, /* Vanguard */
XTAL_12MHz = 12000000,
XTAL_12_096MHz = 12096000,
XTAL_12_288MHz = 12288000, /* Sega Model 3 digital audio board */
XTAL_13_3MHz = 13300000, /* BMC bowling */
XTAL_13_33056MHz = 13330560, /* Taito L */

View File

@ -24,10 +24,16 @@
***************************************************************************/
#define VERBOSE (0)
#if VERBOSE
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
#else
#define LOG(x)
#endif
void CLIB_DECL logerror(const char *text,...);
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/

View File

@ -12,85 +12,312 @@
****************************************************************************
Note: I'm cheating a little bit with the paddle control. The original
game handles the paddle control as following. The paddle is a potentiometer.
Every VBlank signal triggers the start of a voltage ramp. Whenever the
ramp has the same value as the potentiometer, an NMI is generated. In the
NMI code, the current scanline value is used to calculate the value to
put into location $1F in memory. I cheat in this driver by just putting
the paddle value directly into $1F, which has the same net result.
To do:
* Merge with Sprint 1
If you have any questions about how this driver works, don't hesitate to
ask. - Mike Balfour (mab22@po.cwru.edu)
****************************************************************************
CHANGES:
MAB 05 MAR 99 - changed overlay support to use artwork functions
Stephh's notes (based on the games M6502 code and some tests) :
Stephh's notes (based on the games M6502 code and some tests) :
- Each time the game is reset, it is set to "Cavity".
I can't remember if it's the correct behaviour or not,
but the VBLANK interruption is not called in "demo mode".
- You can only select the game after 1st coin is inserted
and before you press BUTTON1 to launch the first ball,
then the VBLANK interruption is no more called.
This means that player 2 plays the same game as player 1.
- Each time the game is reset, it is set to "Cavity".
I can't remember if it's the correct behaviour or not,
but the VBLANK interruption is not called in "demo mode".
- You can only select the game after 1st coin is inserted
and before you press BUTTON1 to launch the first ball,
then the VBLANK interruption is no more called.
This means that player 2 plays the same game as player 1.
***************************************************************************/
#include "driver.h"
#include "sound/dac.h"
#include "includes/sbrkout.h"
#include "sbrkout.lh"
/*************************************
*
* Temporary sound hardware
* Constants
*
*************************************/
#define TIME_4V ATTOTIME_IN_USEC(4075000/4/1000)
#define MAIN_CLOCK XTAL_12_096MHz
#define TIME_4V ATTOTIME_IN_HZ(MAIN_CLOCK/2/256/2/4)
static UINT8 *sbrkout_sound;
static WRITE8_HANDLER( sbrkout_dac_w )
/*************************************
*
* Globals
*
*************************************/
static emu_timer *scanline_timer;
static emu_timer *pot_timer;
static tilemap *bg_tilemap;
static UINT8 sync2_value;
static UINT8 pot_mask[2];
static UINT8 pot_trigger[2];
/*************************************
*
* Prototypes
*
*************************************/
static TIMER_CALLBACK( scanline_callback );
static TIMER_CALLBACK( pot_trigger_callback );
/*************************************
*
* Machine setup
*
*************************************/
static MACHINE_START( sbrkout )
{
sbrkout_sound[offset]=data;
}
static TIMER_CALLBACK( sbrkout_tones_4V )
{
static int vlines=0;
if ((*sbrkout_sound) & vlines)
DAC_data_w(0,255);
else
DAC_data_w(0,0);
vlines = (vlines+1) % 16;
memory_set_bankptr(1, &videoram[0x380]);
scanline_timer = timer_alloc(scanline_callback, NULL);
pot_timer = timer_alloc(pot_trigger_callback, NULL);
state_save_register_global(sync2_value);
state_save_register_global_array(pot_mask);
state_save_register_global_array(pot_trigger);
}
static MACHINE_RESET( sbrkout )
{
timer_pulse(TIME_4V, NULL, 0, sbrkout_tones_4V);
timer_adjust(scanline_timer, video_screen_get_time_until_pos(0, 0, 0), 0, attotime_never);
}
/*************************************
*
* Palette generation
* Interrupts
*
*************************************/
static PALETTE_INIT( sbrkout )
static TIMER_CALLBACK( scanline_callback )
{
palette_set_color(machine,0,MAKE_RGB(0x00,0x00,0x00));
palette_set_color(machine,1,MAKE_RGB(0xff,0xff,0xff));
int scanline = param;
/* force a partial update before anything happens */
video_screen_update_partial(0, scanline);
/* if this is a rising edge of 16V, assert the CPU interrupt */
if (scanline % 32 == 16)
cpunum_set_input_line(0, 0, ASSERT_LINE);
/* update the DAC state */
DAC_data_w(0, (videoram[0x380 + 0x11] & (scanline >> 2)) ? 255 : 0);
/* on the VBLANK, read the pot and schedule an interrupt time for it */
if (scanline == machine->screen[0].visarea.max_y + 1)
{
UINT8 potvalue = readinputportbytag("PADDLE");
timer_adjust(pot_timer, video_screen_get_time_until_pos(0, 72 + (potvalue / 2), (potvalue % 2) * 128), 0, attotime_never);
}
/* call us back in 4 scanlines */
scanline += 4;
if (scanline >= machine->screen[0].height)
scanline = 0;
timer_adjust(scanline_timer, video_screen_get_time_until_pos(0, scanline, 0), scanline, attotime_never);
}
static WRITE8_HANDLER( irq_ack_w )
{
cpunum_set_input_line(0, 0, CLEAR_LINE);
}
/*************************************
*
* Inputs
*
*************************************/
static READ8_HANDLER( switches_r )
{
UINT8 result = 0xff;
/* DIP switches are selected by ADR0+ADR1 if ADR3 == 0 */
if ((offset & 0x0b) == 0x00)
result &= (readinputportbytag("DIPS") << 6) | 0x3f;
if ((offset & 0x0b) == 0x01)
result &= (readinputportbytag("DIPS") << 4) | 0x3f;
if ((offset & 0x0b) == 0x02)
result &= (readinputportbytag("DIPS") << 0) | 0x3f;
if ((offset & 0x0b) == 0x03)
result &= (readinputportbytag("DIPS") << 2) | 0x3f;
/* other switches are selected by ADR0+ADR1+ADR2 if ADR4 == 0 */
if ((offset & 0x17) == 0x00)
result &= (readinputportbytag("SELECT") << 7) | 0x7f;
if ((offset & 0x17) == 0x04)
result &= ((pot_trigger[0] & ~pot_mask[0]) << 7) | 0x7f;
if ((offset & 0x17) == 0x05)
result &= ((pot_trigger[1] & ~pot_mask[1]) << 7) | 0x7f;
if ((offset & 0x17) == 0x06)
result &= readinputportbytag("SERVE");
if ((offset & 0x17) == 0x07)
result &= (readinputportbytag("SELECT") << 6) | 0x7f;
return result;
}
static void update_nmi_state(void)
{
if ((pot_trigger[0] & ~pot_mask[0]) | (pot_trigger[1] & ~pot_mask[1]))
cpunum_set_input_line(0, INPUT_LINE_NMI, ASSERT_LINE);
else
cpunum_set_input_line(0, INPUT_LINE_NMI, CLEAR_LINE);
}
static TIMER_CALLBACK( pot_trigger_callback )
{
pot_trigger[param] = 1;
update_nmi_state();
}
static WRITE8_HANDLER( pot_mask1_w )
{
pot_mask[0] = ~offset & 1;
pot_trigger[0] = 0;
update_nmi_state();
}
static WRITE8_HANDLER( pot_mask2_w )
{
pot_mask[1] = ~offset & 1;
pot_trigger[1] = 0;
update_nmi_state();
}
/*************************************
*
* Lamps and other outputs
*
*************************************/
/*
The LEDs are turned on and off by two consecutive memory addresses. The
first address turns them off, the second address turns them on. This is
reversed for the Serve LED, which has a NOT on the signal.
*/
static WRITE8_HANDLER( start_1_led_w )
{
output_set_led_value(0, offset & 1);
}
static WRITE8_HANDLER( start_2_led_w )
{
output_set_led_value(1, offset & 1);
}
static WRITE8_HANDLER( serve_led_w )
{
output_set_led_value(0, ~offset & 1);
}
static WRITE8_HANDLER( coincount_w )
{
coin_counter_w(0, offset & 1);
}
/*************************************
*
* Video timing
*
*************************************/
static READ8_HANDLER( sync_r )
{
int hpos = video_screen_get_hpos(0);
sync2_value = (hpos >= 128 && hpos <= Machine->screen[0].visarea.max_x);
return video_screen_get_vpos(0);
}
static READ8_HANDLER( sync2_r )
{
return (sync2_value << 7) | 0x7f;
}
/*************************************
*
* Background tilemap
*
*************************************/
static TILE_GET_INFO( get_bg_tile_info )
{
int code = (videoram[tile_index] & 0x80) ? videoram[tile_index] : 0;
SET_TILE_INFO(0, code, 0, 0);
}
static VIDEO_START( sbrkout )
{
bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows, TILEMAP_TYPE_PEN, 8, 8, 32, 32);
}
static WRITE8_HANDLER( sbrkout_videoram_w )
{
videoram[offset] = data;
tilemap_mark_tile_dirty(bg_tilemap, offset);
}
/*************************************
*
* Video update
*
*************************************/
static VIDEO_UPDATE( sbrkout )
{
int ball;
tilemap_draw(bitmap, cliprect, bg_tilemap, 0, 0);
for (ball = 2; ball >= 0; ball--)
{
int code = ((videoram[0x380 + 0x18 + ball * 2 + 1] & 0x80) >> 7);
int sx = 31 * 8 - videoram[0x380 + 0x10 + ball * 2];
int sy = 30 * 8 - videoram[0x380 + 0x18 + ball * 2];
drawgfx(bitmap, machine->gfx[1], code, 0, 0, 0, sx, sy, cliprect, TRANSPARENCY_PEN, 0);
}
return 0;
}
@ -101,40 +328,26 @@ static PALETTE_INIT( sbrkout )
*
*************************************/
static ADDRESS_MAP_START( readmem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x001f, 0x001f) AM_READ(input_port_6_r) /* paddle value */
AM_RANGE(0x0000, 0x00ff) AM_READ(MRA8_RAM) /* Zero Page RAM */
AM_RANGE(0x0100, 0x01ff) AM_READ(MRA8_RAM) /* ??? */
AM_RANGE(0x0400, 0x077f) AM_READ(MRA8_RAM) /* Video Display RAM */
AM_RANGE(0x0828, 0x0828) AM_READ(sbrkout_select1_r) /* Select 1 */
AM_RANGE(0x082f, 0x082f) AM_READ(sbrkout_select2_r) /* Select 2 */
AM_RANGE(0x082e, 0x082e) AM_READ(input_port_5_r) /* Serve Switch */
AM_RANGE(0x0830, 0x0833) AM_READ(sbrkout_read_DIPs_r) /* DIP Switches */
AM_RANGE(0x0840, 0x0840) AM_READ(input_port_1_r) /* Coin Switches */
AM_RANGE(0x0880, 0x0880) AM_READ(input_port_2_r) /* Start Switches */
AM_RANGE(0x08c0, 0x08c0) AM_READ(input_port_3_r) /* Self Test Switch */
AM_RANGE(0x0c00, 0x0c00) AM_READ(input_port_4_r) /* Vertical Sync Counter */
AM_RANGE(0x2c00, 0x3fff) AM_READ(MRA8_ROM) /* PROGRAM */
AM_RANGE(0xfff0, 0xffff) AM_READ(MRA8_ROM) /* PROM8 for 6502 vectors */
ADDRESS_MAP_END
static ADDRESS_MAP_START( writemem, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0011, 0x0011) AM_WRITE(sbrkout_dac_w) AM_BASE(&sbrkout_sound) /* Noise Generation Bits */
AM_RANGE(0x0010, 0x0014) AM_WRITE(MWA8_RAM) AM_BASE(&sbrkout_horiz_ram) /* Horizontal Ball Position */
AM_RANGE(0x0018, 0x001d) AM_WRITE(MWA8_RAM) AM_BASE(&sbrkout_vert_ram) /* Vertical Ball Position / ball picture */
AM_RANGE(0x0000, 0x00ff) AM_WRITE(MWA8_RAM) /* WRAM */
AM_RANGE(0x0100, 0x01ff) AM_WRITE(MWA8_RAM) /* ??? */
AM_RANGE(0x0400, 0x07ff) AM_WRITE(sbrkout_videoram_w) AM_BASE(&videoram) /* DISPLAY */
AM_RANGE(0x0c10, 0x0c11) AM_WRITE(sbrkout_serve_led_w) /* Serve LED */
AM_RANGE(0x0c30, 0x0c31) AM_WRITE(sbrkout_start_1_led_w) /* 1 Player Start Light */
AM_RANGE(0x0c40, 0x0c41) AM_WRITE(sbrkout_start_2_led_w) /* 2 Player Start Light */
AM_RANGE(0x0c50, 0x0c51) AM_WRITE(MWA8_RAM) /* NMI Pot Reading Enable */
AM_RANGE(0x0c70, 0x0c71) AM_WRITE(MWA8_RAM) /* Coin Counter */
AM_RANGE(0x0c80, 0x0c80) AM_WRITE(MWA8_NOP) /* Watchdog */
AM_RANGE(0x0e00, 0x0e00) AM_WRITE(MWA8_NOP) /* IRQ Enable? */
AM_RANGE(0x1000, 0x1000) AM_WRITE(MWA8_RAM) /* LSB of Pot Reading */
AM_RANGE(0x2c00, 0x3fff) AM_WRITE(MWA8_ROM) /* PROM1-PROM8 */
/* full memory map derived from schematics */
static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 )
ADDRESS_MAP_FLAGS( AMEF_ABITS(14) )
AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x380) AM_RAMBANK(1)
AM_RANGE(0x0400, 0x07ff) AM_READWRITE(MRA8_RAM, sbrkout_videoram_w) AM_BASE(&videoram)
AM_RANGE(0x0800, 0x083f) AM_READ(switches_r)
AM_RANGE(0x0840, 0x0840) AM_MIRROR(0x003f) AM_READ_PORT("COIN")
AM_RANGE(0x0880, 0x0880) AM_MIRROR(0x003f) AM_READ_PORT("START")
AM_RANGE(0x08c0, 0x08c0) AM_MIRROR(0x003f) AM_READ_PORT("SERVICE")
AM_RANGE(0x0c00, 0x0c00) AM_MIRROR(0x03ff) AM_READ(sync_r)
AM_RANGE(0x0c10, 0x0c11) AM_MIRROR(0x000e) AM_WRITE(serve_led_w)
AM_RANGE(0x0c30, 0x0c31) AM_MIRROR(0x000e) AM_WRITE(start_1_led_w)
AM_RANGE(0x0c40, 0x0c41) AM_MIRROR(0x000e) AM_WRITE(start_2_led_w)
AM_RANGE(0x0c50, 0x0c51) AM_MIRROR(0x000e) AM_WRITE(pot_mask1_w)
AM_RANGE(0x0c60, 0x0c61) AM_MIRROR(0x000e) AM_WRITE(pot_mask2_w)
AM_RANGE(0x0c70, 0x0c71) AM_MIRROR(0x000e) AM_WRITE(coincount_w)
AM_RANGE(0x0c80, 0x0c80) AM_MIRROR(0x007f) AM_WRITE(watchdog_reset_w)
AM_RANGE(0x0e00, 0x0e00) AM_MIRROR(0x007f) AM_WRITE(irq_ack_w)
AM_RANGE(0x1000, 0x1000) AM_MIRROR(0x03ff) AM_READ(sync2_r)
AM_RANGE(0x2800, 0x3fff) AM_ROM
ADDRESS_MAP_END
@ -146,73 +359,74 @@ ADDRESS_MAP_END
*************************************/
static INPUT_PORTS_START( sbrkout )
PORT_START /* DSW - fake port, gets mapped to Super Breakout ports */
PORT_START_TAG("DIPS")
PORT_DIPNAME( 0x03, 0x00, DEF_STR( Language ) )
PORT_DIPSETTING( 0x00, DEF_STR( English ) )
PORT_DIPSETTING( 0x01, DEF_STR( German ) )
PORT_DIPSETTING( 0x02, DEF_STR( French ) )
PORT_DIPSETTING( 0x03, DEF_STR( Spanish ) )
PORT_DIPNAME( 0x0C, 0x08, DEF_STR( Coinage ) )
PORT_DIPSETTING( 0x0C, DEF_STR( 2C_1C ) )
PORT_DIPNAME( 0x0c, 0x08, DEF_STR( Coinage ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
PORT_DIPNAME( 0x70, 0x00, "Extended Play" )
/* Progressive */
PORT_DIPSETTING( 0x10, "200" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x20, "400" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x30, "600" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x40, "900" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x50, "1200" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x60, "1600" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x70, "2000" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x10, "200" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x00)
PORT_DIPSETTING( 0x20, "400" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x00)
PORT_DIPSETTING( 0x30, "600" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x00)
PORT_DIPSETTING( 0x40, "900" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x00)
PORT_DIPSETTING( 0x50, "1200" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x00)
PORT_DIPSETTING( 0x60, "1600" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x00)
PORT_DIPSETTING( 0x70, "2000" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x00)
/* Double */
PORT_DIPSETTING( 0x10, "200" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x20, "400" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x30, "600" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x40, "800" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x50, "1000" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x60, "1200" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x70, "1500" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x10, "200" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x20, "400" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x30, "600" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x40, "800" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x50, "1000" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x60, "1200" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x02)
PORT_DIPSETTING( 0x70, "1500" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x02)
/* Cavity */
PORT_DIPSETTING( 0x10, "200" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x04)
PORT_DIPSETTING( 0x20, "300" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x04)
PORT_DIPSETTING( 0x30, "400" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x04)
PORT_DIPSETTING( 0x40, "700" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x04)
PORT_DIPSETTING( 0x50, "900" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x04)
PORT_DIPSETTING( 0x60, "1100" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x04)
PORT_DIPSETTING( 0x70, "1400" ) PORT_CONDITION("SELECT",0x07,PORTCOND_EQUALS,0x04)
PORT_DIPSETTING( 0x10, "200" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x20, "300" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x30, "400" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x40, "700" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x50, "900" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x60, "1100" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x70, "1400" ) PORT_CONDITION("SELECT",0x03,PORTCOND_EQUALS,0x01)
PORT_DIPSETTING( 0x00, DEF_STR( None ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Lives ) )
PORT_DIPSETTING( 0x80, "3" )
PORT_DIPSETTING( 0x00, "5" )
PORT_START /* IN0 */
PORT_BIT ( 0x40, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT ( 0x80, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_START_TAG("COIN")
PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN2 )
PORT_START /* IN1 */
PORT_BIT ( 0x40, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT ( 0x80, IP_ACTIVE_LOW, IPT_START2 )
PORT_START_TAG("START")
PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
PORT_START /* IN2 */
PORT_BIT ( 0x40, IP_ACTIVE_LOW, IPT_TILT )
PORT_START_TAG("SERVICE")
PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_TILT )
PORT_SERVICE( 0x80, IP_ACTIVE_LOW )
PORT_START /* IN3 */
PORT_BIT ( 0xFF, IP_ACTIVE_LOW, IPT_VBLANK )
PORT_START_TAG("SERVE")
PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_START /* IN4 */
PORT_BIT ( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON1 )
PORT_START /* IN5 */
PORT_BIT( 0xff, 0x00, IPT_PADDLE ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_REVERSE
PORT_START_TAG("PADDLE")
PORT_BIT( 0xff, 0x00, IPT_PADDLE ) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_CENTERDELTA(0)
PORT_START_TAG("SELECT") /* IN6 - fake port, used to set the game select dial */
PORT_CONFNAME( 0x07, 0x01, "Game Select" )
PORT_CONFSETTING( 0x01, "Progressive" )
PORT_CONFNAME( 0x03, 0x00, "Game Select" )
PORT_CONFSETTING( 0x00, "Progressive" )
PORT_CONFSETTING( 0x02, "Double" )
PORT_CONFSETTING( 0x04, "Cavity" )
PORT_CONFSETTING( 0x01, "Cavity" )
INPUT_PORTS_END
@ -263,30 +477,28 @@ GFXDECODE_END
static MACHINE_DRIVER_START( sbrkout )
/* basic machine hardware */
MDRV_CPU_ADD(M6502,375000) /* 375 KHz? Should be 750KHz? */
MDRV_CPU_PROGRAM_MAP(readmem,writemem)
MDRV_CPU_VBLANK_INT(sbrkout_interrupt,1)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(DEFAULT_REAL_60HZ_VBLANK_DURATION)
MDRV_CPU_ADD(M6502,MAIN_CLOCK/16) /* 375 KHz? Should be 750KHz? */
MDRV_CPU_PROGRAM_MAP(main_map,0)
MDRV_MACHINE_START(sbrkout)
MDRV_MACHINE_RESET(sbrkout)
MDRV_WATCHDOG_VBLANK_INIT(8)
/* video hardware */
MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_SCREEN_SIZE(32*8, 28*8)
MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
MDRV_GFXDECODE(sbrkout)
MDRV_PALETTE_LENGTH(2)
MDRV_PALETTE_INIT(sbrkout)
MDRV_SCREEN_ADD("main", 0)
MDRV_SCREEN_RAW_PARAMS(MAIN_CLOCK/2, 384, 0, 256, 262, 0, 224)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_PALETTE_INIT(black_and_white)
MDRV_VIDEO_START(sbrkout)
MDRV_VIDEO_UPDATE(sbrkout)
/* sound hardware */
MDRV_SPEAKER_STANDARD_MONO("mono")
MDRV_SOUND_ADD(DAC, 0)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MACHINE_DRIVER_END
@ -300,11 +512,10 @@ MACHINE_DRIVER_END
*************************************/
ROM_START( sbrkout )
ROM_REGION( 0x10000, REGION_CPU1, 0 )
ROM_REGION( 0x4000, REGION_CPU1, 0 )
ROM_LOAD( "033453.c1", 0x2800, 0x0800, CRC(a35d00e3) SHA1(53617ed1d362e82d6f45abd66056bffe23300e3b) )
ROM_LOAD( "033454.d1", 0x3000, 0x0800, CRC(d42ea79a) SHA1(66c9b29226cde36d1ac6d1e81f34ebb5c79eded4) )
ROM_LOAD( "033455.e1", 0x3800, 0x0800, CRC(e0a6871c) SHA1(1bdfa73d7b8d91e1c68b7847fc310cac314ee02d) )
ROM_RELOAD( 0xf800, 0x0800 )
ROM_REGION( 0x0400, REGION_GFX1, ROMREGION_DISPOSE )
ROM_LOAD( "033280.p4", 0x0000, 0x0200, CRC(5a69ce85) SHA1(ad9078d12495c350738bdb0b1e1b6120d9e01f60) )
@ -315,7 +526,7 @@ ROM_START( sbrkout )
ROM_REGION( 0x0120, REGION_PROMS, 0 )
ROM_LOAD( "006400.m2", 0x0000, 0x0100, CRC(b8094b4c) SHA1(82dc6799a19984f3b204ee3aeeb007e55afc8be3) ) /* sync (not used) */
ROM_LOAD( "006401.e2", 0x0100, 0x0020, CRC(857df8db) SHA1(06313d5bde03220b2bc313d18e50e4bb1d0cfbbb) ) /* unknown */
ROM_LOAD( "006401.e2", 0x0100, 0x0020, CRC(857df8db) SHA1(06313d5bde03220b2bc313d18e50e4bb1d0cfbbb) ) /* memory mapper */
ROM_END
@ -326,4 +537,4 @@ ROM_END
*
*************************************/
GAMEL( 1978, sbrkout, 0, sbrkout, sbrkout, 0, ROT270, "Atari", "Super Breakout", 0, layout_sbrkout )
GAMEL( 1978, sbrkout, 0, sbrkout, sbrkout, 0, ROT270, "Atari", "Super Breakout", GAME_SUPPORTS_SAVE, layout_sbrkout )

View File

@ -1,26 +0,0 @@
/*************************************************************************
Atari Super Breakout hardware
*************************************************************************/
/*----------- defined in machine/sbrkout.c -----------*/
WRITE8_HANDLER( sbrkout_serve_led_w );
WRITE8_HANDLER( sbrkout_start_1_led_w );
WRITE8_HANDLER( sbrkout_start_2_led_w );
READ8_HANDLER( sbrkout_read_DIPs_r );
INTERRUPT_GEN( sbrkout_interrupt );
READ8_HANDLER( sbrkout_select1_r );
READ8_HANDLER( sbrkout_select2_r );
/*----------- defined in video/sbrkout.c -----------*/
extern UINT8 *sbrkout_horiz_ram;
extern UINT8 *sbrkout_vert_ram;
WRITE8_HANDLER( sbrkout_videoram_w );
VIDEO_START( sbrkout );
VIDEO_UPDATE( sbrkout );

View File

@ -1,110 +0,0 @@
/*************************************************************************
Atari Super Breakout hardware
*************************************************************************/
#include "driver.h"
#include "cpu/m6502/m6502.h"
#include "sbrkout.h"
#define SBRKOUT_PROGRESSIVE 0x00
#define SBRKOUT_DOUBLE 0x01
#define SBRKOUT_CAVITY 0x02
static int sbrkout_game_switch = SBRKOUT_PROGRESSIVE;
/***************************************************************************
Interrupt
Super Breakout has a three-position dial used to select which game to
play - Progressive, Double, and Cavity. We use the interrupt to check
for a key press representing one of these three choices and set our
game switch appropriately. We can't just check for key values at the time
the game checks the game switch, because we would probably lose a *lot* of
key presses. Also, MAME doesn't currently support a switch control like
DIP switches that's used as a runtime control.
***************************************************************************/
INTERRUPT_GEN( sbrkout_interrupt )
{
int game_switch=input_port_7_r(0);
if (game_switch & 0x01)
sbrkout_game_switch=SBRKOUT_PROGRESSIVE;
else if (game_switch & 0x02)
sbrkout_game_switch=SBRKOUT_DOUBLE;
else if (game_switch & 0x04)
sbrkout_game_switch=SBRKOUT_CAVITY;
cpunum_set_input_line(0, 0, HOLD_LINE);
}
READ8_HANDLER( sbrkout_select1_r )
{
if (sbrkout_game_switch==SBRKOUT_CAVITY)
return 0x80;
else return 0x00;
}
READ8_HANDLER( sbrkout_select2_r )
{
if (sbrkout_game_switch==SBRKOUT_DOUBLE)
return 0x80;
else return 0x00;
}
#ifdef UNUSED_FUNCTION
WRITE8_HANDLER( sbrkout_irq_w )
{
/* generate irq */
cpunum_set_input_line(0,M6502_IRQ_LINE,HOLD_LINE);
}
#endif
/***************************************************************************
Read DIPs
We remap all of our DIP switches from a single byte to four bytes. This is
because some of the DIP switch settings would be spread across multiple
bytes, and MAME doesn't currently support that.
***************************************************************************/
READ8_HANDLER( sbrkout_read_DIPs_r )
{
switch (offset)
{
/* DSW */
case 0x00: return ((input_port_0_r(0) & 0x03) << 6);
case 0x01: return ((input_port_0_r(0) & 0x0C) << 4);
case 0x02: return ((input_port_0_r(0) & 0xC0) << 0);
case 0x03: return ((input_port_0_r(0) & 0x30) << 2);
/* Just in case */
default: return 0xFF;
}
}
/***************************************************************************
Lamps
The LEDs are turned on and off by two consecutive memory addresses. The
first address turns them off, the second address turns them on. This is
reversed for the Serve LED, which has a NOT on the signal.
***************************************************************************/
WRITE8_HANDLER( sbrkout_start_1_led_w )
{
set_led_status(0,offset & 1);
}
WRITE8_HANDLER( sbrkout_start_2_led_w )
{
set_led_status(1,offset & 1);
}
WRITE8_HANDLER( sbrkout_serve_led_w )
{
set_led_status(2,~offset & 1);
}

View File

@ -492,7 +492,7 @@ $(MAMEOBJ)/atari.a: \
$(DRIVERS)/rampart.o $(VIDEO)/rampart.o \
$(DRIVERS)/relief.o $(VIDEO)/relief.o \
$(DRIVERS)/runaway.o $(VIDEO)/runaway.o \
$(DRIVERS)/sbrkout.o $(MACHINE)/sbrkout.o $(VIDEO)/sbrkout.o \
$(DRIVERS)/sbrkout.o \
$(DRIVERS)/shuuz.o $(VIDEO)/shuuz.o \
$(DRIVERS)/skullxbo.o $(VIDEO)/skullxbo.o \
$(DRIVERS)/skydiver.o $(AUDIO)/skydiver.o $(VIDEO)/skydiver.o \

View File

@ -1,58 +0,0 @@
/*************************************************************************
Atari Super Breakout hardware
*************************************************************************/
#include "driver.h"
#include "includes/sbrkout.h"
UINT8 *sbrkout_horiz_ram;
UINT8 *sbrkout_vert_ram;
static tilemap *bg_tilemap;
WRITE8_HANDLER( sbrkout_videoram_w )
{
videoram[offset] = data;
tilemap_mark_tile_dirty(bg_tilemap, offset);
}
static TILE_GET_INFO( get_bg_tile_info )
{
int code = (videoram[tile_index] & 0x80) ? videoram[tile_index] : 0;
SET_TILE_INFO(0, code, 0, 0);
}
VIDEO_START( sbrkout )
{
bg_tilemap = tilemap_create(get_bg_tile_info, tilemap_scan_rows,
TILEMAP_TYPE_PEN, 8, 8, 32, 32);
}
static void draw_balls(running_machine *machine, mame_bitmap *bitmap, const rectangle *cliprect)
{
int ball;
for (ball=2; ball>=0; ball--)
{
int code = ((sbrkout_vert_ram[ball * 2 + 1] & 0x80) >> 7);
int sx = 31 * 8 - sbrkout_horiz_ram[ball * 2];
int sy = 30 * 8 - sbrkout_vert_ram[ball * 2];
drawgfx(bitmap, machine->gfx[1],
code, 0,
0, 0,
sx, sy,
cliprect,
TRANSPARENCY_PEN, 0);
}
}
VIDEO_UPDATE( sbrkout )
{
tilemap_draw(bitmap, cliprect, bg_tilemap, 0, 0);
draw_balls(machine, bitmap, cliprect);
return 0;
}