// license:GPL-2.0+
// copyright-holders:Jarek Burczynski, Phil Stroffolino, Tomasz Slanina
/**************************************************************************
Change Lanes
(C) Taito 1983
Jarek Burczynski
Phil Stroffolino
Tomasz Slanina
***************************************************************************/
#include "emu.h"
#include "includes/changela.h"
#include "cpu/z80/z80.h"
#include "machine/74259.h"
#include "machine/watchdog.h"
#include "sound/ay8910.h"
#include "speaker.h"
#include "changela.lh"
READ8_MEMBER(changela_state::mcu_r)
{
//osd_printf_debug("Z80 MCU R = %x\n", m_mcu_out);
return m_mcu_out;
}
/* latch LS374 at U39 */
WRITE8_MEMBER(changela_state::mcu_w)
{
m_mcu_in = data;
if (!BIT(m_port_c_out, 2))
m_mcu->pa_w(space, 0, data);
}
/*********************************
MCU
*********************************/
WRITE8_MEMBER(changela_state::changela_68705_port_a_w)
{
m_port_a_out = data;
}
WRITE8_MEMBER(changela_state::changela_68705_port_c_w)
{
/* PC3 is connected to the CLOCK input of the LS374, so we latch the data on rising edge */
if (BIT(data, 3) && ~BIT(m_port_c_out, 3))
m_mcu_out = m_port_a_out & (BIT(m_port_c_out, 2) ? 0xff : m_mcu_in);
/* PC2 is connected to the /OE input of the LS374 */
if (BIT(data, 2))
m_mcu->pa_w(space, 0, BIT(data, 2) ? 0xff : m_mcu_in);
m_port_c_out = data;
}
/* U30 */
READ8_MEMBER(changela_state::changela_24_r)
{
return (BIT(m_port_c_out, 1) << 3) | 0x07; /* bits 2,1,0-N/C inputs */
}
READ8_MEMBER(changela_state::changela_25_r)
{
//collisions on bits 3,2, bits 1,0-N/C inputs
return (m_tree1_col << 3) | (m_tree0_col << 2) | 0x03;
}
READ8_MEMBER(changela_state::changela_30_r)
{
return ioport("WHEEL")->read() & 0x0f; //wheel control (clocked input) signal on bits 3,2,1,0
}
READ8_MEMBER(changela_state::changela_31_r)
{
/* If the new value is less than the old value, and it did not wrap around,
or if the new value is greater than the old value, and it did wrap around,
then we are moving LEFT. */
uint8_t curr_value = ioport("WHEEL")->read();
if ((curr_value < m_prev_value_31 && (m_prev_value_31 - curr_value) < 0x80)
|| (curr_value > m_prev_value_31 && (curr_value - m_prev_value_31) > 0x80))
m_dir_31 = 1;
if ((m_prev_value_31 < curr_value && (curr_value - m_prev_value_31) < 0x80)
|| (m_prev_value_31 > curr_value && (m_prev_value_31 - curr_value) > 0x80))
m_dir_31 = 0;
m_prev_value_31 = curr_value;
//wheel UP/DOWN control signal on bit 3, collisions on bits:2,1,0
return (m_dir_31 << 3) | (m_left_bank_col << 2) | (m_right_bank_col << 1) | m_boat_shore_col;
}
READ8_MEMBER(changela_state::changela_2c_r)
{
int val = ioport("IN0")->read();
val = (val & 0x30) | ((val & 1) << 7) | (((val & 1) ^ 1) << 6);
return val;
}
READ8_MEMBER(changela_state::changela_2d_r)
{
/* the schems are unreadable - i'm not sure it is V8 (page 74, SOUND I/O BOARD SCHEMATIC 1 OF 2, FIGURE 24 - in the middle on the right side) */
int v8 = 0;
int gas;
if ((m_screen->vpos() & 0xf8) == 0xf8)
v8 = 1;
/* Gas pedal is made up of 2 switches, 1 active low, 1 active high */
switch (ioport("IN1")->read() & 0x03)
{
case 0x02:
gas = 0x80;
break;
case 0x01:
gas = 0x00;
break;
default:
gas = 0x40;
break;
}
return (ioport("IN1")->read() & 0x20) | gas | (v8 << 4);
}
WRITE_LINE_MEMBER(changela_state::mcu_pc_0_w)
{
m_mcu->pc_w(machine().dummy_space(), 0, 0xfe | state);
}
WRITE_LINE_MEMBER(changela_state::collision_reset_0_w)
{
m_collision_reset = state;
}
WRITE_LINE_MEMBER(changela_state::collision_reset_1_w)
{
m_tree_collision_reset = state;
}
WRITE_LINE_MEMBER(changela_state::coin_counter_1_w)
{
machine().bookkeeping().coin_counter_w(0, state);
}
WRITE_LINE_MEMBER(changela_state::coin_counter_2_w)
{
machine().bookkeeping().coin_counter_w(1, state);
}
void changela_state::changela_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x83ff).ram().share("spriteram"); /* OBJ0 RAM */
map(0x9000, 0x97ff).ram().share("videoram"); /* OBJ1 RAM */
map(0xa000, 0xa07f).w(FUNC(changela_state::changela_colors_w)).share("colorram"); /* Color 93419 RAM 64x9(nine!!!) bits A0-used as the 8-th bit data input (d0-d7->normal, a0->d8) */
map(0xb000, 0xbfff).rom();
map(0xc000, 0xc7ff).rw(FUNC(changela_state::changela_mem_device_r), FUNC(changela_state::changela_mem_device_w)); /* RAM4 (River Bed RAM); RAM5 (Tree RAM) */
/* LS138 - U16 */
map(0xc800, 0xc800).nopw(); /* not connected */
map(0xc900, 0xc900).w(FUNC(changela_state::changela_mem_device_select_w)); /* selects the memory device to be accessible at 0xc000-0xc7ff */
map(0xca00, 0xca00).w(FUNC(changela_state::changela_slope_rom_addr_hi_w));
map(0xcb00, 0xcb00).w(FUNC(changela_state::changela_slope_rom_addr_lo_w));
map(0xd000, 0xd001).rw("ay1", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w));
map(0xd010, 0xd011).rw("ay2", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_data_w));
/* LS259 - U44 */
map(0xd020, 0xd027).w("outlatch", FUNC(ls259_device::write_d0));
/* LS139 - U24 */
map(0xd024, 0xd024).r(FUNC(changela_state::changela_24_r));
map(0xd025, 0xd025).r(FUNC(changela_state::changela_25_r));
map(0xd028, 0xd028).r(FUNC(changela_state::mcu_r));
map(0xd02c, 0xd02c).r(FUNC(changela_state::changela_2c_r));
map(0xd02d, 0xd02d).r(FUNC(changela_state::changela_2d_r));
map(0xd030, 0xd030).rw(FUNC(changela_state::changela_30_r), FUNC(changela_state::mcu_w));
map(0xd031, 0xd031).r(FUNC(changela_state::changela_31_r));
map(0xe000, 0xe000).w("watchdog", FUNC(watchdog_timer_device::reset_w)); /* Watchdog */
map(0xf000, 0xf7ff).ram(); /* RAM2 (Processor RAM) */
}
static INPUT_PORTS_START( changela )
PORT_START("DSWA") /* DSWA */
PORT_DIPNAME( 0x07, 0x01, "Steering Wheel Ratio" ) PORT_DIPLOCATION("SWA:1,2,3")
//PORT_DIPSETTING( 0x00, "?" ) /* Not documented */
PORT_DIPSETTING( 0x01, "Recommended Setting" )
//PORT_DIPSETTING( 0x02, "?" ) /* Not documented */
//PORT_DIPSETTING( 0x03, "?" ) /* Not documented */
//PORT_DIPSETTING( 0x04, "?" ) /* Not documented */
//PORT_DIPSETTING( 0x05, "?" ) /* Not documented */
//PORT_DIPSETTING( 0x06, "?" ) /* Not documented */
//PORT_DIPSETTING( 0x07, "?" ) /* Not documented */
PORT_DIPNAME( 0x08, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SWA:4")
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x00, "Ignore Memory Failures" ) PORT_DIPLOCATION("SWA:5")
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x00, DEF_STR( Controls ) ) PORT_DIPLOCATION("SWA:6")
PORT_DIPSETTING( 0x20, DEF_STR( Joystick ) )
PORT_DIPSETTING( 0x00, "Steering Wheel" )
PORT_DIPNAME( 0x40, 0x40, "Diagnostic" ) PORT_DIPLOCATION("SWA:7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x00, DEF_STR( Players ) ) PORT_DIPLOCATION("SWA:8")
PORT_DIPSETTING( 0x80, "1" )
PORT_DIPSETTING( 0x00, "2" )
PORT_START("DSWB") /* DSWB */
PORT_DIPNAME( 0x03, 0x00, "Max Bonus Fuels" ) PORT_DIPLOCATION("SWB:1,2")
PORT_DIPSETTING( 0x01, "1" )
PORT_DIPSETTING( 0x02, "2" )
PORT_DIPSETTING( 0x03, "3" )
PORT_DIPSETTING( 0x00, "99" )
PORT_DIPNAME( 0x0c, 0x08, "Game Difficulty" ) PORT_DIPLOCATION("SWB:3,4")
PORT_DIPSETTING( 0x00, DEF_STR( Very_Easy) )
PORT_DIPSETTING( 0x04, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x08, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x0c, DEF_STR( Hard ) )
PORT_DIPNAME( 0x30, 0x20, "Traffic Difficulty" ) PORT_DIPLOCATION("SWB:5,6")
PORT_DIPSETTING( 0x00, DEF_STR( Very_Easy) )
PORT_DIPSETTING( 0x10, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x20, DEF_STR( Medium ) )
PORT_DIPSETTING( 0x30, DEF_STR( Hard ) )
PORT_DIPNAME( 0x40, 0x00, "Land Collisions Enabled" ) PORT_DIPLOCATION("SWB:7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x00, "Car Collision Enabled" ) PORT_DIPLOCATION("SWB:8")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("DSWC") /* DSWC - coinage */
PORT_DIPNAME( 0xf0, 0x10, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SWC:5,6,7,8")
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
PORT_DIPSETTING( 0x90, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0xa0, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0x10, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0xb0, DEF_STR( 2C_3C ) )
PORT_DIPSETTING( 0xc0, DEF_STR( 2C_4C ) )
PORT_DIPSETTING( 0x20, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0xd0, DEF_STR( 2C_5C ) )
PORT_DIPSETTING( 0xe0, DEF_STR( 2C_6C ) )
PORT_DIPSETTING( 0x30, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0xf0, DEF_STR( 2C_7C ) )
PORT_DIPSETTING( 0x40, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x50, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x60, DEF_STR( 1C_6C ) )
PORT_DIPSETTING( 0x70, DEF_STR( 1C_7C ) )
PORT_DIPNAME( 0x0f, 0x01, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SWC:1,2,3,4")
PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
PORT_DIPSETTING( 0x09, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0a, DEF_STR( 2C_2C ) )
PORT_DIPSETTING( 0x01, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x0b, DEF_STR( 2C_3C ) )
PORT_DIPSETTING( 0x0c, DEF_STR( 2C_4C ) )
PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0d, DEF_STR( 2C_5C ) )
PORT_DIPSETTING( 0x0e, DEF_STR( 2C_6C ) )
PORT_DIPSETTING( 0x03, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0f, DEF_STR( 2C_7C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x05, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x06, DEF_STR( 1C_6C ) )
PORT_DIPSETTING( 0x07, DEF_STR( 1C_7C ) )
PORT_START("DSWD") /* DSWD - bonus */
PORT_DIPNAME( 0x01, 0x01, "Right Slot" ) PORT_DIPLOCATION("SWD:1")
PORT_DIPSETTING( 0x01, "On Right (Bottom) Counter" )
PORT_DIPSETTING( 0x00, "On Left (Top) Counter" )
PORT_DIPNAME( 0x02, 0x00, "Left Slot" ) PORT_DIPLOCATION("SWD:2")
PORT_DIPSETTING( 0x02, "On Right (Bottom) Counter" )
PORT_DIPSETTING( 0x00, "On Left (Top) Counter" )
PORT_DIPNAME( 0x1c, 0x00, "Credits For Bonus" ) PORT_DIPLOCATION("SWD:3,4,5")
PORT_DIPSETTING( 0x00, "0" )
PORT_DIPSETTING( 0x04, "1" )
PORT_DIPSETTING( 0x08, "2" )
PORT_DIPSETTING( 0x0c, "3" )
PORT_DIPSETTING( 0x10, "4" )
PORT_DIPSETTING( 0x14, "5" )
PORT_DIPSETTING( 0x18, "6" )
PORT_DIPSETTING( 0x1c, "7" )
PORT_DIPUNUSED_DIPLOC( 0x20, IP_ACTIVE_LOW, "SWD:6" ) /* Listed as "Unused" */
PORT_DIPNAME( 0x40, 0x00, "'King Of The World' Name Length" )PORT_DIPLOCATION("SWD:7")
PORT_DIPSETTING( 0x40, "3 Letters" )
PORT_DIPSETTING( 0x00, "Long" )
PORT_DIPNAME( 0x80, 0x00, "'King Of The World' Name" ) PORT_DIPLOCATION("SWD:8")
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("MCU") /* MCU */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
#ifdef THREE_STATE_SWITCH
PORT_DIPNAME( 0x30, 0x30, "Self Test Switch" ) PORT_DIPLOCATION("SWT:1,2")
//PORT_DIPSETTING( 0x00, "?" ) /* Not possible, 3-state switch */
PORT_DIPSETTING( 0x20, "Free Game" ) /* "Puts a credit on the game without increasing the coin counter." */
PORT_DIPSETTING( 0x10, DEF_STR( Test ) )
PORT_DIPSETTING( 0x30, DEF_STR( Off ) )
#else // schematics don't make it clear exactly how this switch is supposed to work
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Free Game/Self-Test")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
#endif
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_START("IN0") /* 0xDx2C */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Gear Shift") PORT_CODE(KEYCODE_SPACE) PORT_TOGGLE /* Gear shift */
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("DSWA", 0x20, EQUALS, 0x20)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("DSWA", 0x20, EQUALS, 0x20)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* FWD - negated bit 7 */
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* REV - gear position */
PORT_START("IN1") /* 0xDx2D */
PORT_BIT( 0x03, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00, 0x02) PORT_SENSITIVITY(10) PORT_KEYDELTA(1) //gas pedal
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_TILT )
//PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) //gas1
//PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) //gas2
PORT_START("WHEEL") /* 0xDx30 DRIVING_WHEEL */
PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(50) PORT_KEYDELTA(8) PORT_CONDITION("DSWA", 0x20, EQUALS, 0x00)
INPUT_PORTS_END
TIMER_DEVICE_CALLBACK_MEMBER(changela_state::changela_scanline)
{
int scanline = param;
if(scanline == 256) // vblank irq
m_maincpu->set_input_line_and_vector(0, HOLD_LINE,0xdf); // Z80
else if(((scanline % 64) == 0)) // timer irq, 3 times per given vblank field
m_maincpu->set_input_line_and_vector(0, HOLD_LINE,0xcf); // Z80
}
INTERRUPT_GEN_MEMBER(changela_state::chl_mcu_irq)
{
m_mcu->pulse_input_line(0, m_mcu->minimum_quantum_time());
}
void changela_state::machine_start()
{
/* video */
save_item(NAME(m_slopeROM_bank));
save_item(NAME(m_tree_en));
save_item(NAME(m_horizon));
save_item(NAME(m_mem_dev_selected));
save_item(NAME(m_v_count_river));
save_item(NAME(m_v_count_tree));
save_item(NAME(m_tree_on));
/* mcu */
save_item(NAME(m_port_a_out));
save_item(NAME(m_port_c_out));
save_item(NAME(m_mcu_out));
save_item(NAME(m_mcu_in));
/* misc */
save_item(NAME(m_tree0_col));
save_item(NAME(m_tree1_col));
save_item(NAME(m_left_bank_col));
save_item(NAME(m_right_bank_col));
save_item(NAME(m_boat_shore_col));
save_item(NAME(m_collision_reset));
save_item(NAME(m_tree_collision_reset));
save_item(NAME(m_prev_value_31));
save_item(NAME(m_dir_31));
m_port_a_out = 0xff;
m_port_c_out = 0xff;
}
void changela_state::machine_reset()
{
/* video */
m_slopeROM_bank = 0;
m_tree_en = 0;
m_horizon = 0;
m_mem_dev_selected = 0;
m_v_count_river = 0;
m_v_count_tree = 0;
m_tree_on[0] = 0;
m_tree_on[1] = 0;
/* mcu */
m_mcu_out = 0;
m_mcu_in = 0;
/* misc */
m_tree0_col = 0;
m_tree1_col = 0;
m_left_bank_col = 0;
m_right_bank_col = 0;
m_boat_shore_col = 0;
m_collision_reset = 0;
m_tree_collision_reset = 0;
m_prev_value_31 = 0;
m_dir_31 = 0;
}
void changela_state::changela(machine_config &config)
{
Z80(config, m_maincpu, 5000000);
m_maincpu->set_addrmap(AS_PROGRAM, &changela_state::changela_map);
TIMER(config, "scantimer").configure_scanline(FUNC(changela_state::changela_scanline), "screen", 0, 1);
M68705P3(config, m_mcu, 2500000);
m_mcu->portb_r().set_ioport("MCU");
m_mcu->porta_w().set(FUNC(changela_state::changela_68705_port_a_w));
m_mcu->portc_w().set(FUNC(changela_state::changela_68705_port_c_w));
m_mcu->set_vblank_int("screen", FUNC(changela_state::chl_mcu_irq));
ls259_device &outlatch(LS259(config, "outlatch")); // U44 on Sound I/O Board
outlatch.q_out_cb<0>().set(FUNC(changela_state::collision_reset_0_w));
outlatch.q_out_cb<1>().set(FUNC(changela_state::coin_counter_1_w));
outlatch.q_out_cb<2>().set(FUNC(changela_state::coin_counter_2_w));
outlatch.q_out_cb<4>().set(FUNC(changela_state::mcu_pc_0_w));
outlatch.q_out_cb<5>().set(FUNC(changela_state::collision_reset_1_w));
WATCHDOG_TIMER(config, "watchdog");
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_size(32*8, 262); /* vert size is a guess */
m_screen->set_visarea(0*8, 32*8-1, 4*8, 32*8-1);
m_screen->set_screen_update(FUNC(changela_state::screen_update_changela));
m_screen->set_palette(m_palette);
PALETTE(config, m_palette).set_entries(0x40);
SPEAKER(config, "mono").front_center();
ay8910_device &ay1(AY8910(config, "ay1", 1250000));
ay1.port_a_read_callback().set_ioport("DSWA");
ay1.port_b_read_callback().set_ioport("DSWB");
ay1.add_route(ALL_OUTPUTS, "mono", 0.50);
ay8910_device &ay2(AY8910(config, "ay2", 1250000));
ay2.port_a_read_callback().set_ioport("DSWC");
ay2.port_b_read_callback().set_ioport("DSWD");
ay2.add_route(ALL_OUTPUTS, "mono", 0.50);
}
ROM_START( changela )
ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 code */
ROM_LOAD( "cl25a", 0x0000, 0x2000, CRC(38530a60) SHA1(0b0ef1abe11c5271fcd1671322b77165217553c3) )
ROM_LOAD( "cl24a", 0x2000, 0x2000, CRC(2fcf4a82) SHA1(c33355e2d4d3fab32c8d713a680ec0fceedab341) )
ROM_LOAD( "cl23", 0x4000, 0x2000, CRC(08385891) SHA1(d8d66664ec25db067d5a4a6c35ec0ac65b9e0c6a) )
ROM_LOAD( "cl22", 0x6000, 0x2000, CRC(796e0abd) SHA1(64dd9fc1f9bc44519a253ef0c02e181dd13904bf) )
ROM_LOAD( "cl27", 0xb000, 0x1000, CRC(3668afb8) SHA1(bcfb788baf806edcb129ea9f9dcb1d4260684773) )
ROM_REGION( 0x00800, "mcu", 0 ) /* 68705P3 */
ROM_LOAD( "cl38a", 0x0000, 0x800, CRC(b70156ce) SHA1(c5eab8bbd65c4f587426298da4e22f991ce01dde) )
ROM_REGION( 0x4000, "gfx1", 0 ) /* tile data */
ROM_LOAD( "cl111", 0x0000, 0x2000, CRC(41c0149d) SHA1(3ea53a3821b044b3d0451fec1b4ee2c28da393ca) )
ROM_LOAD( "cl113", 0x2000, 0x2000, CRC(ddf99926) SHA1(e816b88302c5639c7284f4845d450f232d63a10c) )
ROM_REGION( 0x1000, "gfx2", 0 ) /* obj 1 data */
ROM_LOAD( "cl46", 0x0000, 0x1000, CRC(9c0a7d28) SHA1(fac9180ea0d9aeea56a84b35cc0958f0dd86a801) )
ROM_REGION( 0x8000, "user1", 0 ) /* obj 0 data */
ROM_LOAD( "cl100", 0x0000, 0x2000, CRC(3fa9e4fa) SHA1(9abd7df5fcf143a0c476bd8c8753c5ea294b9f74) )
ROM_LOAD( "cl99", 0x2000, 0x2000, CRC(67b27b9e) SHA1(7df0f93851959359218c8d2272e30d242a77039d) )
ROM_LOAD( "cl98", 0x4000, 0x2000, CRC(bffe4149) SHA1(5cf0b98f9d342bd06d575c565ea01bbd79f5e04b) )
ROM_LOAD( "cl97", 0x6000, 0x2000, CRC(5abab8f9) SHA1(f5156855bbcdf0740fd44520386318ee53ebbf9a) )
ROM_REGION( 0x1000, "user2", 0 ) /* math tables: SLOPE ROM (river-tree schematic page 1/3) */
ROM_LOAD( "cl44", 0x0000, 0x1000, CRC(160d2bc7) SHA1(2609208c2bd4618ea340923ee01af69278980c36) ) /* first and 2nd half identical */
ROM_REGION( 0x3000, "user3", 0 ) /* math tables: TREE ROM (river-tree schematic page 3/3)*/
ROM_LOAD( "cl7", 0x0000, 0x0800, CRC(01e3efca) SHA1(b26203787f105ba32773e37035c39253050f9c82) ) /* fixed bits: 0xxxxxxx */
ROM_LOAD( "cl9", 0x1000, 0x2000, CRC(4e53cdd0) SHA1(6255411cfdccbe2c581c83f9127d582623453c3a) )
ROM_REGION( 0x0020, "proms", 0 )
ROM_LOAD( "cl88", 0x0000, 0x0020, CRC(da4d6625) SHA1(2d9a268973518252eb36f479ab650af8c16c885c) ) /* math train state machine */
ROM_END
GAMEL( 1983, changela, 0, changela, changela, changela_state, empty_init, ROT180, "Taito Corporation", "Change Lanes", MACHINE_SUPPORTS_SAVE, layout_changela )