diff options
Diffstat (limited to 'trunk/src/mame/drivers/acefruit.c')
-rw-r--r-- | trunk/src/mame/drivers/acefruit.c | 738 |
1 files changed, 738 insertions, 0 deletions
diff --git a/trunk/src/mame/drivers/acefruit.c b/trunk/src/mame/drivers/acefruit.c new file mode 100644 index 00000000000..fcebbc3fa29 --- /dev/null +++ b/trunk/src/mame/drivers/acefruit.c @@ -0,0 +1,738 @@ +/*************************************************************************** + +Ace Video Fruit Machine hardware +(c)1981-1982 ACE Leisure + +Driver by SMF & Guddler 04/02/2007 +Inputs and Dip Switches by Stephh + +***************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "machine/nvram.h" + +#include "sidewndr.lh" + + +class acefruit_state : public driver_device +{ +public: + acefruit_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) { } + + UINT8 *m_spriteram; + UINT8 *m_colorram; + UINT8 *m_videoram; + emu_timer *m_refresh_timer; +}; + + + +static void acefruit_update_irq(running_machine &machine, int vpos ) +{ + acefruit_state *state = machine.driver_data<acefruit_state>(); + int col; + int row = vpos / 8; + + for( col = 0; col < 32; col++ ) + { + int tile_index = ( col * 32 ) + row; + int color = state->m_colorram[ tile_index ]; + + switch( color ) + { + case 0x0c: + cputag_set_input_line(machine, "maincpu", 0, HOLD_LINE ); + break; + } + } +} + + +static TIMER_CALLBACK( acefruit_refresh ) +{ + acefruit_state *state = machine.driver_data<acefruit_state>(); + int vpos = machine.primary_screen->vpos(); + + machine.primary_screen->update_partial(vpos ); + acefruit_update_irq(machine, vpos ); + + vpos = ( ( vpos / 8 ) + 1 ) * 8; + + state->m_refresh_timer->adjust( machine.primary_screen->time_until_pos(vpos) ); +} + +static VIDEO_START( acefruit ) +{ + acefruit_state *state = machine.driver_data<acefruit_state>(); + state->m_refresh_timer = machine.scheduler().timer_alloc(FUNC(acefruit_refresh)); +} + +static INTERRUPT_GEN( acefruit_vblank ) +{ + acefruit_state *state = device->machine().driver_data<acefruit_state>(); + device_set_input_line(device, 0, HOLD_LINE ); + state->m_refresh_timer->adjust( attotime::zero ); +} + +static SCREEN_UPDATE( acefruit ) +{ + acefruit_state *state = screen->machine().driver_data<acefruit_state>(); + int startrow = cliprect->min_y / 8; + int endrow = cliprect->max_y / 8; + int row; + int col; + + for( row = startrow; row <= endrow; row++ ) + { + int spriterow = 0; + int spriteindex = 0; + int spriteparameter = 0; + + for( col = 0; col < 32; col++ ) + { + int tile_index = ( col * 32 ) + row; + int code = state->m_videoram[ tile_index ]; + int color = state->m_colorram[ tile_index ]; + + if( color < 0x4 ) + { + drawgfx_opaque( bitmap, cliprect, screen->machine().gfx[ 1 ], code, color, 0, 0, col * 16, row * 8 ); + } + else if( color >= 0x5 && color <= 0x7 ) + { + int y; + int x; + static const int spriteskip[] = { 1, 2, 4 }; + int spritesize = spriteskip[ color - 5 ]; + const gfx_element *gfx = screen->machine().gfx[ 0 ]; + + for( x = 0; x < 16; x++ ) + { + int sprite = ( state->m_spriteram[ ( spriteindex / 64 ) % 6 ] & 0xf ) ^ 0xf; + const UINT8 *gfxdata = gfx_element_get_data(gfx, sprite); + + for( y = 0; y < 8; y++ ) + { + UINT16 *dst = BITMAP_ADDR16( bitmap, y + ( row * 8 ), x + ( col * 16 ) ); + *( dst ) = *( gfxdata + ( ( spriterow + y ) * gfx->line_modulo ) + ( ( spriteindex % 64 ) >> 1 ) ); + } + + spriteindex += spritesize; + } + } + else + { + int y; + int x; + + for( x = 0; x < 16; x++ ) + { + for( y = 0; y < 8; y++ ) + { + UINT16 *dst = BITMAP_ADDR16( bitmap, y + ( row * 8 ), x + ( col * 16 ) ); + *( dst ) = 0; + } + } + + if( color == 0x8 ) + { + if( spriteparameter == 0 ) + { + spriteindex = code & 0xf; + } + else + { + spriterow = ( ( code >> 0 ) & 0x3 ) * 8; + spriteindex += ( ( code >> 2 ) & 0x1 ) * 16; + } + + spriteparameter = !spriteparameter; + } + else if( color == 0xc ) + { + /* irq generated in acefruit_update_irq() */ + } + } + } + } + + return 0; +} + +static CUSTOM_INPUT( sidewndr_payout_r ) +{ + int bit_mask = (FPTR)param; + + switch (bit_mask) + { + case 0x01: + return ((input_port_read(field.machine(), "PAYOUT") & bit_mask) >> 0); + case 0x02: + return ((input_port_read(field.machine(), "PAYOUT") & bit_mask) >> 1); + default: + logerror("sidewndr_payout_r : invalid %02X bit_mask\n",bit_mask); + return 0; + } +} + +static CUSTOM_INPUT( starspnr_coinage_r ) +{ + int bit_mask = (FPTR)param; + + switch (bit_mask) + { + case 0x01: + return ((input_port_read(field.machine(), "COINAGE") & bit_mask) >> 0); + case 0x02: + return ((input_port_read(field.machine(), "COINAGE") & bit_mask) >> 1); + case 0x04: + return ((input_port_read(field.machine(), "COINAGE") & bit_mask) >> 2); + case 0x08: + return ((input_port_read(field.machine(), "COINAGE") & bit_mask) >> 3); + default: + logerror("starspnr_coinage_r : invalid %02X bit_mask\n",bit_mask); + return 0; + } +} + +static CUSTOM_INPUT( starspnr_payout_r ) +{ + int bit_mask = (FPTR)param; + + switch (bit_mask) + { + case 0x01: + return ((input_port_read(field.machine(), "PAYOUT") & bit_mask) >> 0); + case 0x02: + return ((input_port_read(field.machine(), "PAYOUT") & bit_mask) >> 1); + case 0x04: + return ((input_port_read(field.machine(), "PAYOUT") & bit_mask) >> 2); + default: + logerror("starspnr_payout_r : invalid %02X bit_mask\n",bit_mask); + return 0; + } +} + +static WRITE8_HANDLER( acefruit_colorram_w ) +{ + acefruit_state *state = space->machine().driver_data<acefruit_state>(); + state->m_colorram[ offset ] = data & 0xf; +} + +static WRITE8_HANDLER( acefruit_coin_w ) +{ + /* TODO: ? */ +} + +static WRITE8_HANDLER( acefruit_sound_w ) +{ + /* TODO: ? */ +} + +static WRITE8_HANDLER( acefruit_lamp_w ) +{ + int i; + + for( i = 0; i < 8; i++ ) + { + output_set_lamp_value( ( offset * 8 ) + i, ( data >> i ) & 1 ); + } +} + +static WRITE8_HANDLER( acefruit_solenoid_w ) +{ + int i; + + for( i = 0; i < 8; i++ ) + { + output_set_indexed_value( "solenoid", i, ( data >> i ) & 1 ); + } +} + +static PALETTE_INIT( acefruit ) +{ + /* sprites */ + palette_set_color( machine, 0, MAKE_RGB(0x00, 0x00, 0x00) ); + palette_set_color( machine, 1, MAKE_RGB(0x00, 0x00, 0xff) ); + palette_set_color( machine, 2, MAKE_RGB(0x00, 0xff, 0x00) ); + palette_set_color( machine, 3, MAKE_RGB(0xff, 0x7f, 0x00) ); + palette_set_color( machine, 4, MAKE_RGB(0xff, 0x00, 0x00) ); + palette_set_color( machine, 5, MAKE_RGB(0xff, 0xff, 0x00) ); + palette_set_color( machine, 6, MAKE_RGB(0xff, 0xff, 0xff) ); + palette_set_color( machine, 7, MAKE_RGB(0x7f, 0x3f, 0x1f) ); + + /* tiles */ + palette_set_color( machine, 8, MAKE_RGB(0x00, 0x00, 0x00) ); + palette_set_color( machine, 9, MAKE_RGB(0xff, 0xff, 0xff) ); + palette_set_color( machine, 10, MAKE_RGB(0x00, 0x00, 0x00) ); + palette_set_color( machine, 11, MAKE_RGB(0x00, 0x00, 0xff) ); + palette_set_color( machine, 12, MAKE_RGB(0x00, 0x00, 0x00) ); + palette_set_color( machine, 13, MAKE_RGB(0x00, 0xff, 0x00) ); + palette_set_color( machine, 14, MAKE_RGB(0x00, 0x00, 0x00) ); + palette_set_color( machine, 15, MAKE_RGB(0xff, 0x00, 0x00) ); +} + +static ADDRESS_MAP_START( acefruit_map, AS_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x1fff) AM_ROM + AM_RANGE(0x2000, 0x20ff) AM_RAM AM_SHARE("nvram") + AM_RANGE(0x4000, 0x43ff) AM_RAM AM_BASE_MEMBER(acefruit_state, m_videoram) + AM_RANGE(0x4400, 0x47ff) AM_RAM_WRITE(acefruit_colorram_w) AM_BASE_MEMBER(acefruit_state, m_colorram) + AM_RANGE(0x8000, 0x8000) AM_READ_PORT("IN0") + AM_RANGE(0x8001, 0x8001) AM_READ_PORT("IN1") + AM_RANGE(0x8002, 0x8002) AM_READ_PORT("IN2") + AM_RANGE(0x8003, 0x8003) AM_READ_PORT("IN3") + AM_RANGE(0x8004, 0x8004) AM_READ_PORT("IN4") + AM_RANGE(0x8005, 0x8005) AM_READ_PORT("IN5") + AM_RANGE(0x8006, 0x8006) AM_READ_PORT("IN6") + AM_RANGE(0x8007, 0x8007) AM_READ_PORT("IN7") + AM_RANGE(0x6000, 0x6005) AM_RAM AM_BASE_MEMBER(acefruit_state, m_spriteram) + AM_RANGE(0xa000, 0xa001) AM_WRITE(acefruit_lamp_w) + AM_RANGE(0xa002, 0xa003) AM_WRITE(acefruit_coin_w) + AM_RANGE(0xa004, 0xa004) AM_WRITE(acefruit_solenoid_w) + AM_RANGE(0xa005, 0xa006) AM_WRITE(acefruit_sound_w) + AM_RANGE(0xc000, 0xc000) AM_WRITE(watchdog_reset_w) + AM_RANGE(0xe000, 0xffff) AM_ROM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( acefruit_io, AS_IO, 8 ) + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x00, 0x00) AM_NOP /* ? */ +ADDRESS_MAP_END + +static INPUT_PORTS_START( sidewndr ) + PORT_START("IN0") // 0 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME( "Stop Nudge/Nudge Up or Down" ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME( "Gamble" ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 ) /* "Cash in" */ + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_VBLANK ) /* active low or high?? */ + PORT_BIT( 0xd8, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN1") // 1 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME( "Sidewind" ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME( "Collect" ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) /* "Cash in" */ + PORT_DIPNAME( 0x08, 0x00, "Accountacy System Texts" ) + PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN2") // 2 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME( "Cancel/Clear" ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME( "Refill" ) PORT_TOGGLE + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 ) /* "Token in" - also "Refill" when "Refill" mode ON */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(sidewndr_payout_r, (void *)0x01) + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN3") // 3 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME( "Hold/Nudge 1" ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME( "Accountancy System" ) PORT_TOGGLE + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN4 ) /* "50P in" */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(sidewndr_payout_r, (void *)0x02) + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN4") // 4 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME( "Hold/Nudge 2" ) + PORT_DIPNAME( 0x02, 0x00, "Allow Clear Data" ) /* in "Accountancy System" mode */ + PORT_DIPSETTING( 0x02, DEF_STR( No ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) + PORT_DIPNAME( 0x04, 0x04, "Lamp 11 always ON" ) /* code at 0x173a - write lamp status at 0x01ed */ + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Yes ) ) + PORT_DIPNAME( 0x08, 0x00, "Sounds" ) /* data in 0x206b and 0x206c - out sound at 0x193e */ + PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN5") // 5 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_NAME( "Hold/Nudge 3" ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME( "Test Program" ) PORT_TOGGLE + PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN6") // 6 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_NAME( "Hold/Nudge 4" ) + /* I don't know exactly what this bit is supposed to do :( + I only found that when bit is LOW, no data is updated + (check "Accountancy System" mode). And when you switch + it from LOW to HIGH, previous saved values are back + (check for example the number of credits). */ + PORT_DIPNAME( 0x02, 0x02, "Save Data" ) /* code at 0x1773 */ + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x02, DEF_STR( On ) ) + PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN7") // 7 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) /* next in "Accountancy System" mode */ + PORT_DIPNAME( 0x02, 0x00, "Clear Credits on Reset" ) /* also affects rolls */ + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("PAYOUT") // fake port to handle settings via multiple input ports + PORT_DIPNAME( 0x03, 0x00, "Payout %" ) + PORT_DIPSETTING( 0x00, "74%" ) + PORT_DIPSETTING( 0x02, "78%" ) + PORT_DIPSETTING( 0x01, "82%" ) + PORT_DIPSETTING( 0x03, "86%" ) +INPUT_PORTS_END + +static INPUT_PORTS_START( spellbnd ) + PORT_INCLUDE(sidewndr) + + PORT_MODIFY("IN0") + PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) /* before COIN4 test - code at 0x0994 */ + PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_BIT( 0xd0, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_MODIFY("IN1") + PORT_DIPNAME( 0x08, 0x08, "Accountacy System Texts" ) /* bit test is inverted compared to 'sidewndr' */ + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + + PORT_MODIFY("IN2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME( "Cancel" ) /* see IN4 bit 0 in "Accountancy System" mode */ + + PORT_MODIFY("IN4") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE3 ) PORT_NAME( "Clear Data" ) /* in "Accountancy System" mode */ + /* Similar to 'sidewndr' but different addresses */ + PORT_DIPNAME( 0x04, 0x04, "Lamp 11 always ON" ) /* code at 0x072a - write lamp status at 0x00ff */ + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Yes ) ) + /* Similar to 'sidewndr' but different addresses */ + PORT_DIPNAME( 0x08, 0x00, "Sounds" ) /* data in 0x2088 and 0x2089 - out sound at 0x012d */ + PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + + PORT_MODIFY("IN6") + /* I don't know exactly what this bit is supposed to do :( + I only found that when bit is LOW, no data is updated + (check "Accountancy System" mode). */ + PORT_DIPNAME( 0x02, 0x02, "Save Data" ) /* code at 0x0763 (similar to 'sidewndr') and 0x18db */ + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x02, DEF_STR( On ) ) + + PORT_MODIFY("IN7") + PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) /* code at 0x04a8 */ + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_BIT( 0xf4, IP_ACTIVE_LOW, IPT_UNKNOWN ) +INPUT_PORTS_END + +/* I've only mapped the known inputs after comparison with 'spellbnd' and the ones known to do something */ +static INPUT_PORTS_START( starspnr ) + PORT_START("IN0") // 0 + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME( "Gamble" ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 ) + /* tested at 0xef77 after IN5 bit 1 and before IN2 bit 2 - after coins are tested - table at 0xefa5 (3 bytes) */ + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_VBLANK ) /* active low or high?? */ + + PORT_START("IN1") // 1 + /* tested at 0xe77c - call from 0x012c */ + /* tested at 0xeffb after IN6 bit 2 - invalid code after 0xf000 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME( "Collect/Cancel" ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN2 ) + /* tested at 0xeed7 with IN1 bit 3 - before coins are tested - table at 0xef55 (4 * 3 bytes) */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(starspnr_coinage_r, (void *)0x08) /* to be confirmed */ + + PORT_START("IN2") // 2 + /* tested at 0xe83c */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0xe5ab - after "Collect" and "Gamble" buttons */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0xef82 after IN5 bit 1 and after IN1 bit 3 - after coins are tested - table at 0xefa8 (3 bytes) */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0xeeba with IN3 bit 3 - before coins are tested - table at 0xef55 (4 * 3 bytes) */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(starspnr_coinage_r, (void *)0x02) /* to be confirmed */ + /* tested at 0x1b0f */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN3") // 3 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME( "Hold 1" ) + /* tested at 0xe8ea and 0xecbe */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0xeeba with IN2 bit 3 - before coins are tested - table at 0xef55 (4 * 3 bytes) */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(starspnr_coinage_r, (void *)0x01) /* to be confirmed */ + /* tested at 0x0178 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN4") // 4 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME( "Hold 2" ) + /* tested at 0x064e */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0xed86 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0xeed7 with IN1 bit 3 - before coins are tested - table at 0xef55 (4 * 3 bytes) */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(starspnr_coinage_r, (void *)0x04) /* to be confirmed */ + + PORT_START("IN5") // 5 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_NAME( "Hold 3" ) + /* tested at 0xef68 before IN1 bit 3 and before IN2 bit 2 - after coins are tested - table at 0xefa2 (3 bytes) */ + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0xec6f */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0x1d60 with IN6 bit 3 and IN7 bit 3 - table at 0x1d90 (8 * 3 bytes) */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(starspnr_payout_r, (void *)0x01) /* to be confirmed */ + /* tested at 0xe312 and 0xe377 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN6") // 6 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_NAME( "Hold 4" ) + /* tested at 0xee42, 0xee5e and 0xeff5 before IN1 bit 0 - invalid code after 0xf000 */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0x1d60 with IN5 bit 3 and IN7 bit 3 - table at 0x1d90 (8 * 3 bytes) */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(starspnr_payout_r, (void *)0x02) /* to be confirmed */ + /* tested at 0xe8dd and 0xec1c */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("IN7") // 7 + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) + PORT_DIPNAME( 0x02, 0x00, "Clear Credits on Reset" ) + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + /* tested at 0xedcb */ + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + /* tested at 0x1d60 with IN5 bit 3 and IN6 bit 3 - table at 0x1d90 (8 * 3 bytes) */ + PORT_BIT( 0x08, 0x00, IPT_SPECIAL) PORT_CUSTOM(starspnr_payout_r, (void *)0x04) /* to be confirmed */ + /* tested at 0xec2a */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START("COINAGE") // fake port to handle settings via multiple input ports + PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_A ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x01, DEF_STR( 1C_4C ) ) + PORT_DIPSETTING( 0x02, "1 Coin/10 Credits" ) + PORT_DIPSETTING( 0x03, "1 Coin/25 Credits" ) + PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Coin_B ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x04, DEF_STR( 1C_4C ) ) + PORT_DIPSETTING( 0x08, "1 Coin/10 Credits" ) + PORT_DIPSETTING( 0x0c, "1 Coin/25 Credits" ) + + PORT_START("PAYOUT") // fake port to handle settings via multiple input ports + PORT_DIPNAME( 0x07, 0x07, "Payout %" ) + PORT_DIPSETTING( 0x00, "30%" ) + PORT_DIPSETTING( 0x01, "40%" ) + PORT_DIPSETTING( 0x02, "50%" ) + PORT_DIPSETTING( 0x03, "55%" ) + PORT_DIPSETTING( 0x04, "60%" ) + PORT_DIPSETTING( 0x05, "70%" ) + PORT_DIPSETTING( 0x06, "75%" ) + PORT_DIPSETTING( 0x07, "80%" ) +INPUT_PORTS_END + +static const gfx_layout charlayout = +{ + 16,8, /* 8*8 characters doubled horizontally */ + 256, /* 256 characters */ + 1, /* 1 bit per pixel */ + { 0 }, + { 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7}, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, + 8*8 +}; + +static const gfx_layout spritelayout = +{ + 32,32, /* 32*32 sprites */ + 16, /* 16 sprites */ + 3, /* 3 bits per pixel */ + /* Offset to the start of each bit */ + { 0, 256*8*8, 256*8*8*2 }, + /* Offset to the start of each byte */ + { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31 + }, + /* Offset to the start of each line */ + { + 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32, + 8*32, 9*32, 10*32, 11*32, 12*32, 13*32, 14*32, 15*32, + 16*32, 17*32, 18*32, 19*32, 20*32, 21*32, 22*32, 23*32, + 24*32, 25*32, 26*32, 27*32, 28*32, 29*32, 30*32, 31*32 + }, + /* Offset to next sprite (also happens to be number of bits per sprite) */ + 32*32 /* every sprite takes 128 bytes */ +}; + +static GFXDECODE_START( acefruit ) + GFXDECODE_ENTRY( "gfx1", 0x0000, spritelayout, 0, 1 ) + GFXDECODE_ENTRY( "gfx1", 0x1800, charlayout, 8, 4 ) +GFXDECODE_END + +static MACHINE_CONFIG_START( acefruit, acefruit_state ) + + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", Z80, 2500000) /* 2.5MHz */ + MCFG_CPU_PROGRAM_MAP(acefruit_map) + MCFG_CPU_IO_MAP(acefruit_io) + MCFG_GFXDECODE(acefruit) + MCFG_CPU_VBLANK_INT("screen", acefruit_vblank) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) + MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MCFG_SCREEN_SIZE(512, 256) + MCFG_SCREEN_VISIBLE_AREA(0, 511, 0, 255) + MCFG_SCREEN_UPDATE(acefruit) + + MCFG_PALETTE_LENGTH(16) + + MCFG_NVRAM_ADD_0FILL("nvram") + + MCFG_PALETTE_INIT(acefruit) + MCFG_VIDEO_START(acefruit) + + /* sound hardware */ +MACHINE_CONFIG_END + +static DRIVER_INIT( sidewndr ) +{ + UINT8 *ROM = machine.region( "maincpu" )->base(); + /* replace "ret nc" ( 0xd0 ) with "di" */ + ROM[ 0 ] = 0xf3; + /* this is either a bad dump or the cpu core should set the carry flag on reset */ +} + +/*************************************************************************** + + Game driver(s) + +***************************************************************************/ + +ROM_START( sidewndr ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "2_h09.bin", 0x000000, 0x000800, BAD_DUMP CRC(141f3b0c) SHA1(1704feba950fe7aa939b9ed54c37264d10527d11) ) + ROM_LOAD( "2_h10.bin", 0x000800, 0x000800, CRC(36a2d4af) SHA1(2388e22245497240e5721895d94d2ccd1f579eff) ) + ROM_LOAD( "2_h11.bin", 0x001000, 0x000800, CRC(e2932643) SHA1(e1c0cd5d0cd332519432cbefa8718362a6cd1ccc) ) + ROM_LOAD( "2_h12.bin", 0x001800, 0x000800, CRC(26af0b1f) SHA1(36f0e54982688b9d5a24a6986a847ac69ee0a355) ) + + ROM_REGION( 0x2000, "gfx1", 0 ) /* 8k for graphics */ + ROM_LOAD( "2_h05.bin", 0x000000, 0x000800, CRC(64b64cff) SHA1(c11f2bd2af68ae7f104b711deb7f6509fdbaeb8f) ) + ROM_LOAD( "2_h06.bin", 0x000800, 0x000800, CRC(6b96a586) SHA1(6d5ab8fefe37ca4dbc5057ebf31f12b33dbdf5c0) ) + ROM_LOAD( "2_h07.bin", 0x001000, 0x000800, CRC(3a8e68a2) SHA1(2ffe07360f57f0f11ecf326f00905747d9b66811) ) + ROM_LOAD( "2_h08.bin", 0x001800, 0x000800, CRC(bd19a758) SHA1(3fa812742f34643f66c67cb9bdb1d4d732c4f44d) ) +ROM_END + +ROM_START( spellbnd ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "h9.bin", 0x000000, 0x000800, CRC(9919fcfa) SHA1(04167b12ee9e60ef891893a305a35d3f2eccb0bb) ) + ROM_LOAD( "h10.bin", 0x000800, 0x000800, CRC(90502d00) SHA1(3bdd859d9146df2eb97b4517c446182569a55a46) ) + ROM_LOAD( "h11.bin", 0x001000, 0x000800, CRC(7375166c) SHA1(f05b01941423fd36e0a5d3aa913a594e4e7aa5d4) ) + ROM_LOAD( "h12.bin", 0x001800, 0x000800, CRC(4546c68c) SHA1(92104e2005fc772ea9f70451d9d674f95d3f0ba9) ) + + ROM_REGION( 0x2000, "gfx1", 0 ) /* 8k for graphics */ + ROM_LOAD( "h5.bin", 0x000000, 0x000800, CRC(198da32c) SHA1(bf6c4ddcda0503095d310e08057dd88154952ef4) ) + ROM_LOAD( "h6.bin", 0x000800, 0x000800, CRC(e777130f) SHA1(3421c6f399e5ec749f1908f6b4ebff7761c6c5d9) ) + ROM_LOAD( "h7.bin", 0x001000, 0x000800, CRC(bfed5b8f) SHA1(f95074e8809297eec67da9d7e33ae1dd1c5eabc0) ) + ROM_LOAD( "h8.bin", 0x001800, 0x000800, CRC(05da2b71) SHA1(3a263f605ecc9e4dca9ce0ba815af16e28bf9bc8) ) +ROM_END + +/* +Starspinner +ACE, 1982? + +PCB Layout +---------- + +|---------------------------------------------------------------------------| +| | +| XTAL BAT 2114 | +| | +| 14-1-102 P1 | +| | +| | +| | +| 14-1-102 | +| | +| 5 2114 | +| | +| 6 2114 14-1-102 | +| | +| 7 | +| | +| 8 5501 5501 14-1-102 | +| | +| h9 16-1-101 | +| | +| h10 16-1-101 | +| | +| h11 Z80 16-1-101 | +| | +| h12 P2 | +| | +| DSWA DSWB | +| | +|---------------------------------------------------------------------------| + +Notes: + Z80 - NEC D780C running at ? MHz (DIP40) + 5501 - Toshiba TC5501P 256 x4 SRAM (DIP22) + 2114 - NEC uPD2114LC 1k x8 DRAM (DIP18) + XTAL - ? MHz + BAT - VARTA Ni-Cd 3.6V 100 mAh + DSWA - 8-way DIP switch + DSWB - 8-way DIP switch + P1 - 4x10 pin connector to power supply + P2 - 4x10 pin connector to control panel +*/ + +ROM_START( starspnr ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "h9.h9", 0x00e000, 0x0800, CRC(083068aa) SHA1(160a5f3bf33d0a53354f98295cd67022762928b6) ) + ROM_CONTINUE( 0x000000, 0x0800 ) + ROM_LOAD( "h10.h10", 0x00e800, 0x0800, CRC(a0a96e55) SHA1(de4dc0da5a1f358085817690cc6bdc8d94a849f8) ) + ROM_CONTINUE( 0x000800, 0x0800 ) + ROM_LOAD( "h11.h11", 0x00f000, 0x0800, BAD_DUMP CRC(ab045396) SHA1(8b3aea0b0d55f62d5b6fbd39664beb93559d2213) ) /* bad dump : invalid code in both halves ! */ + ROM_CONTINUE( 0x001000, 0x0800 ) + ROM_LOAD( "h12.h12", 0x00f800, 0x0800, CRC(8571f3f5) SHA1(e8b60a604a4a0368b6063b15b328c68f351cb740) ) /* bad dump ? nothing of interest 0xf800-0xffff */ + ROM_CONTINUE( 0x001800, 0x0800 ) + + ROM_REGION( 0x2000, "gfx1", 0 ) /* 8k for graphics */ + ROM_LOAD( "5.h5", 0x000000, 0x000800, CRC(df49876f) SHA1(68077304f096491baeddc1d6b4dc62f90de71903) ) + ROM_LOAD( "6.h6", 0x000800, 0x000800, CRC(d992e2f6) SHA1(7841efec7d81689c82b8da501cce743436e7e8d4) ) + ROM_LOAD( "7.h7", 0x001000, 0x000800, CRC(d5a40e88) SHA1(5cac8d85123720cdbb8b4630b14a27cf0ceef33f) ) + ROM_LOAD( "8.h8", 0x001800, 0x000800, CRC(0dd38c3c) SHA1(4da0cd00c76d3be2164f141ccd8c72dd9578ee61) ) + + ROM_REGION( 0x300, "proms", 0 ) + ROM_LOAD( "16-1-101.b9", 0x0000, 0x0100, NO_DUMP ) + ROM_LOAD( "16-1-101.b10", 0x0100, 0x0100, NO_DUMP ) + ROM_LOAD( "16-1-101.b11", 0x0200, 0x0100, NO_DUMP ) +ROM_END + +/* no information about this one */ +ROM_START( acefruit ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "vp-h9.bin", 0x00e000, 0x0800, CRC(f595daf7) SHA1(be5abd34fd06f73cd80f5b15902d158e33705c8f) ) + ROM_CONTINUE( 0x000000, 0x0800 ) + ROM_LOAD( "vp-h10.bin", 0x00e800, 0x0800, CRC(b0539100) SHA1(763f31f72f55c3322b24e127b37130d37daa5216) ) + ROM_CONTINUE( 0x000800, 0x0800 ) + ROM_LOAD( "vp-h11.bin", 0x00f000, 0x0800, CRC(fa176072) SHA1(18203278bb9c505f07390f7b95ecf9ab6d7b7122) ) + ROM_CONTINUE( 0x001000, 0x0800 ) + + ROM_REGION( 0x2000, "gfx1", 0 ) /* 8k for graphics */ + ROM_LOAD( "vp-h5.bin", 0x000000, 0x000800, CRC(dfffe063) SHA1(1b860323fe93b7d010fa35167769555a6bd4a49c) ) + ROM_LOAD( "vp-h6.bin", 0x000800, 0x000800, CRC(355203b8) SHA1(959f3599a24293f392e8b10061c39d3244f34c05) ) + ROM_LOAD( "vp-h7.bin", 0x001000, 0x000800, CRC(7784de8a) SHA1(40851724c9b7ef26964462b5e97ad943df4d56e2) ) + ROM_LOAD( "vp-h8.bin", 0x001800, 0x000800, CRC(d587e541) SHA1(902b6c4673b8b989d034d60d3c47f2499f100ba2) ) + + /* there were no proms in the set */ + ROM_REGION( 0x300, "proms", 0 ) + ROM_LOAD( "16-1-101.b9", 0x0000, 0x0100, NO_DUMP ) + ROM_LOAD( "16-1-101.b10", 0x0100, 0x0100, NO_DUMP ) + ROM_LOAD( "16-1-101.b11", 0x0200, 0x0100, NO_DUMP ) +ROM_END + + +GAMEL( 1981?, sidewndr, 0, acefruit, sidewndr, sidewndr, ROT270, "ACE", "Sidewinder", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND, layout_sidewndr ) +GAMEL( 1981?, spellbnd, sidewndr, acefruit, spellbnd, 0, ROT270, "ACE", "Spellbound", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND, layout_sidewndr ) +GAME ( 1982?, starspnr, 0, acefruit, starspnr, 0, ROT270, "ACE", "Starspinner (Dutch/Nederlands)", GAME_NOT_WORKING | GAME_NO_SOUND ) +// inputs need fixing on this one, no idea what it's called either +GAME ( 1982?, acefruit, 0, acefruit, spellbnd, 0, ROT270, "ACE", "unknown ACE fruits game", GAME_NOT_WORKING | GAME_NO_SOUND ) |