segaorun.c: Added motor and lamp outputs. [Howard Casto, hap]

This commit is contained in:
Michaël Banaan Ananas 2013-12-31 02:03:04 +00:00
parent fbf76d2225
commit ab6758443a
2 changed files with 185 additions and 33 deletions

View File

@ -306,6 +306,16 @@ static I8255_INTERFACE(single_ppi_intf)
DEVCB_DRIVER_MEMBER(segaorun_state, video_control_w)
};
static I8255_INTERFACE(deluxe_ppi_intf)
{
DEVCB_DRIVER_MEMBER(segaorun_state, bankmotor_limit_r),
DEVCB_DRIVER_MEMBER(segaorun_state, unknown_porta_w),
DEVCB_DRIVER_MEMBER(segaorun_state, unknown_portb_r),
DEVCB_DRIVER_MEMBER(segaorun_state, bankmotor_pos_w),
DEVCB_DRIVER_MEMBER(segaorun_state, unknown_portc_r),
DEVCB_DRIVER_MEMBER(segaorun_state, video_control_w)
};
//**************************************************************************
@ -359,7 +369,7 @@ WRITE8_MEMBER( segaorun_state::unknown_portb_w )
WRITE8_MEMBER( segaorun_state::video_control_w )
{
// Output port:
// Output port C:
// D7: SG1 -- connects to sprite chip
// D6: SG0 -- connects to mixing
// D5: Screen display (1= blanked, 0= displayed)
@ -373,6 +383,74 @@ WRITE8_MEMBER( segaorun_state::video_control_w )
}
//-------------------------------------------------
// bankmotor_limit_r - bank motor limit switches
// for deluxe cabs
//-------------------------------------------------
READ8_MEMBER( segaorun_state::bankmotor_limit_r )
{
// Input port A
UINT8 ret = 0xff;
// d3: right limit
// d4: center
// d5: left limit
// other bits: ?
UINT8 pos = ioport("ADC3")->read();
// these may need to be calibrated when emulating it in a real cab
const UINT8 right = 0xe0;
const UINT8 center = 0x80;
const UINT8 left = 0x20;
if (pos >= right)
ret ^= 0x08;
else if (pos == center)
ret ^= 0x10;
else if (pos <= left)
ret ^= 0x20;
return ret;
}
//-------------------------------------------------
// bankmotor_pos_w - bank motor control
// for deluxe cabs
//-------------------------------------------------
WRITE8_MEMBER( segaorun_state::bankmotor_pos_w )
{
// Output port B
data &= 0x0f;
if (data == 0)
return;
// motor "position" is 1 - 15, with 8 being centered
// this is converted to speed and direction
if (data < 8)
{
// left
output_set_value("Bank_Motor_Direction", 1);
output_set_value("Bank_Motor_Speed", 8 - data);
}
else if (data == 8)
{
// no movement
output_set_value("Bank_Motor_Direction", 0);
output_set_value("Bank_Motor_Speed", 0);
}
else
{
// right
output_set_value("Bank_Motor_Direction", 2);
output_set_value("Bank_Motor_Speed", data - 8);
}
}
//**************************************************************************
// MEMORY MAPPING
@ -454,6 +532,7 @@ READ16_MEMBER( segaorun_state::misc_io_r )
{
if (!m_custom_io_r.isnull())
return m_custom_io_r(space, offset, mem_mask);
logerror("%06X:misc_io_r - unknown read access to address %04X\n", space.device().safe_pc(), offset * 2);
return open_bus_r(space, 0, mem_mask);
}
@ -470,6 +549,7 @@ WRITE16_MEMBER( segaorun_state::misc_io_w )
m_custom_io_w(space, offset, data, mem_mask);
return;
}
logerror("%06X:misc_io_w - unknown write access to address %04X = %04X & %04X\n", space.device().safe_pc(), offset * 2, data, mem_mask);
}
@ -625,6 +705,9 @@ READ16_MEMBER( segaorun_state::outrun_custom_io_r )
case 0x60/2:
return watchdog_reset_r(space, 0);
default:
break;
}
logerror("%06X:outrun_custom_io_r - unknown read access to address %04X\n", space.device().safe_pc(), offset * 2);
@ -652,8 +735,14 @@ WRITE16_MEMBER( segaorun_state::outrun_custom_io_w )
{
// Output port:
// D7: /MUTE
// D6-D0: unknown
// D5: Vibration motor
// D2: Start lamp
// D1: Brake lamp
// other bits: ?
machine().sound().system_enable(data & 0x80);
output_set_value("Vibration_motor", data >> 5 & 1);
output_set_value("Start_lamp", data >> 2 & 1);
output_set_value("Brake_lamp", data >> 1 & 1);
}
return;
@ -668,7 +757,11 @@ WRITE16_MEMBER( segaorun_state::outrun_custom_io_w )
case 0x70/2:
m_sprites->draw_write(space, offset, data, mem_mask);
return;
default:
break;
}
logerror("%06X:misc_io_w - unknown write access to address %04X = %04X & %04X\n", space.device().safe_pc(), offset * 2, data, mem_mask);
}
@ -697,7 +790,11 @@ READ16_MEMBER( segaorun_state::shangon_custom_io_r )
static const char *const ports[] = { "ADC0", "ADC1", "ADC2", "ADC3" };
return ioport(ports[m_adc_select])->read_safe(0x0010);
}
default:
break;
}
logerror("%06X:misc_io_r - unknown read access to address %04X\n", space.device().safe_pc(), offset * 2);
return open_bus_r(space,0,mem_mask);
}
@ -714,17 +811,28 @@ WRITE16_MEMBER( segaorun_state::shangon_custom_io_w )
switch (offset)
{
case 0x0000/2:
// Output port:
// D7-D6: (ADC1-0)
// D5: Screen display
m_adc_select = (data >> 6) & 3;
m_segaic16vid->segaic16_set_display_enable((data >> 5) & 1);
if (ACCESSING_BITS_0_7)
{
// Output port:
// D7-D6: (ADC1-0)
// D5: Screen display
// D3: Vibration motor
// D2: Start lamp
// other bits: ?
m_adc_select = data >> 6 & 3;
m_segaic16vid->segaic16_set_display_enable(data >> 5 & 1);
output_set_value("Vibration_motor", data >> 3 & 1);
output_set_value("Start_lamp", data >> 2 & 1);
}
return;
case 0x0020/2:
// Output port:
// D0: Sound section reset (1= normal operation, 0= reset)
m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE);
if (ACCESSING_BITS_0_7)
{
// Output port:
// D0: Sound section reset (1= normal operation, 0= reset)
m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE);
}
return;
case 0x3000/2:
@ -734,7 +842,11 @@ WRITE16_MEMBER( segaorun_state::shangon_custom_io_w )
case 0x3020/2:
// ADC trigger
return;
default:
break;
}
logerror("%06X:misc_io_w - unknown write access to address %04X = %04X & %04X\n", space.device().safe_pc(), offset * 2, data, mem_mask);
}
@ -839,7 +951,7 @@ static INPUT_PORTS_START( outrun_generic )
PORT_SERVICE_NO_TOGGLE( 0x02, IP_ACTIVE_LOW )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Gear Shift") PORT_CODE(KEYCODE_SPACE) PORT_TOGGLE
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Gear Shift") PORT_TOGGLE
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
@ -876,6 +988,13 @@ static INPUT_PORTS_START( outrun_generic )
PORT_START("ADC2") // brake
PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_SENSITIVITY(100) PORT_KEYDELTA(40)
/* Bank Motor Position */
/* This is set to the same axis as the wheel to allow for proper ff data in deluxe(Moving) cabs */
/* Move the stick left and right during motor warmup to prevent "engine or limit sw trouble" */
/* On a motion sim this should be binded to the READ pot for the motor */
PORT_START("ADC3")
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x20,0xe0) PORT_SENSITIVITY(100) PORT_KEYDELTA(4) PORT_NAME("Bank Motor Position")
INPUT_PORTS_END
@ -917,7 +1036,7 @@ static INPUT_PORTS_START( toutrun )
PORT_INCLUDE( outrun_generic )
PORT_MODIFY("SERVICE")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Turbo") PORT_CODE(KEYCODE_LSHIFT)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Turbo")
PORT_MODIFY("DSW")
PORT_DIPNAME( 0x03, 0x01, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SWB:1,2")
@ -968,6 +1087,9 @@ static INPUT_PORTS_START( toutrunc )
PORT_DIPNAME( 0x08, 0x08, "Turbo" ) PORT_DIPLOCATION("SWB:4")
// PORT_DIPSETTING( 0x00, DEF_STR( Unused ) )
PORT_DIPSETTING( 0x08, "Use Turbo Shifter" )
PORT_MODIFY("ADC3")
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
@ -983,7 +1105,7 @@ static INPUT_PORTS_START( shangon )
PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Supercharger") PORT_CODE(KEYCODE_LSHIFT)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Supercharger")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )
@ -1007,6 +1129,9 @@ static INPUT_PORTS_START( shangon )
PORT_MODIFY("ADC0") // steering
PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x20,0xe0) PORT_SENSITIVITY(100) PORT_KEYDELTA(4) PORT_REVERSE
PORT_MODIFY("ADC3")
PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
@ -1051,7 +1176,7 @@ static MACHINE_CONFIG_START( outrun_base, segaorun_state )
MCFG_QUANTUM_TIME(attotime::from_hz(6000))
MCFG_I8255_ADD( "i8255", single_ppi_intf )
MCFG_I8255_ADD( "i8255", deluxe_ppi_intf )
MCFG_SEGA_315_5195_MAPPER_ADD("mapper", "maincpu", segaorun_state, memory_mapper, mapper_sound_r, mapper_sound_w)
// video hardware
@ -1085,24 +1210,47 @@ MACHINE_CONFIG_END
//**************************************************************************
static MACHINE_CONFIG_DERIVED( outrundx, outrun_base )
// video hardware
MCFG_SEGA_OUTRUN_SPRITES_ADD("sprites")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( outrun, outrun_base )
// basic machine hardware
MCFG_NVRAM_ADD_0FILL("nvram")
// video hardware
MCFG_SEGA_OUTRUN_SPRITES_ADD("sprites")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( outrun_fd1094, outrun )
// basic machine hardware
MCFG_CPU_REPLACE("maincpu", FD1094, MASTER_CLOCK/4)
MCFG_CPU_PROGRAM_MAP(outrun_map)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( outrunc_fd1094, outrun_fd1094 )
// basic machine hardware
MCFG_CPU_REPLACE("maincpu", FD1094, MASTER_CLOCK/4)
MCFG_CPU_PROGRAM_MAP(outrun_map)
MCFG_DEVICE_REMOVE("i8255")
MCFG_I8255_ADD( "i8255", single_ppi_intf )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( shangon, outrun_base )
// basic machine hardware
MCFG_DEVICE_REMOVE("i8255")
MCFG_I8255_ADD( "i8255", single_ppi_intf )
MCFG_NVRAM_ADD_0FILL("nvram")
// video hardware
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_25MHz/4, 400, 0, 321, 262, 0, 224)
MCFG_SCREEN_UPDATE_DRIVER(segaorun_state, screen_update_shangon)
@ -1111,6 +1259,8 @@ static MACHINE_CONFIG_DERIVED( shangon, outrun_base )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( shangon_fd1089b, shangon )
// basic machine hardware
MCFG_CPU_REPLACE("maincpu", FD1089B, MASTER_CLOCK/4)
MCFG_CPU_PROGRAM_MAP(outrun_map)
MACHINE_CONFIG_END
@ -2237,7 +2387,7 @@ GAME( 1987, shangon2, shangon, shangon_fd1089b, shangon, segaorun_state,shangon
GAME( 1987, shangon1, shangon, shangon_fd1089b, shangon, segaorun_state,shangon, ROT0, "Sega", "Super Hang-On (mini ride-on?, FD1089B 317-0034)", GAME_NOT_WORKING ) // bad program rom
GAME( 1991, shangonle,shangon, shangon, shangon, segaorun_state,shangon, ROT0, "Sega", "Limited Edition Hang-On", 0 )
GAMEL(1989, toutrun, 0, outrun_fd1094, toutrun, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (Out Run upgrade, FD1094 317-0118)", 0, layout_outrun ) // Cabinet determined by dipswitch settings
GAMEL(1989, toutrunj, toutrun, outrun_fd1094, toutrun, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (Japan, Out Run upgrade, FD1094 317-0117)", 0, layout_outrun ) // Cabinet determined by dipswitch settings
GAMEL(1989, toutrun3, toutrun, outrun_fd1094, toutrunc, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (cockpit, FD1094 317-0107)", 0, layout_outrun )
GAMEL(1989, toutrun2, toutrun, outrun_fd1094, toutrunc, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (cockpit, FD1094 317-0106)", 0, layout_outrun )
GAMEL(1989, toutrunj, toutrun, outrun_fd1094, toutrun, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (Japan, Out Run upgrade, FD1094 317-0117)", 0, layout_outrun ) // Cabinet determined by dipswitch settings
GAMEL(1989, toutrun3, toutrun, outrunc_fd1094, toutrunc, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (cockpit, FD1094 317-0107)", 0, layout_outrun )
GAMEL(1989, toutrun2, toutrun, outrunc_fd1094, toutrunc, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (cockpit, FD1094 317-0106)", 0, layout_outrun )
GAMEL(1989, toutrun1, toutrun, outrun_fd1094, toutrunm, segaorun_state,outrun, ROT0, "Sega", "Turbo Out Run (deluxe cockpit, FD1094 317-0109)", 0, layout_outrun )

View File

@ -24,22 +24,22 @@ public:
// construction/destruction
segaorun_state(const machine_config &mconfig, device_type type, const char *tag)
: sega_16bit_common_base(mconfig, type, tag),
m_mapper(*this, "mapper"),
m_maincpu(*this, "maincpu"),
m_subcpu(*this, "subcpu"),
m_soundcpu(*this, "soundcpu"),
m_i8255(*this, "i8255"),
m_nvram(*this, "nvram"),
m_sprites(*this, "sprites"),
m_segaic16vid(*this, "segaic16vid"),
m_segaic16road(*this, "segaic16road"),
m_workram(*this, "workram"),
m_custom_map(NULL),
m_shangon_video(false),
m_scanline_timer(NULL),
m_irq2_state(0),
m_adc_select(0),
m_vblank_irq_state(0)
m_mapper(*this, "mapper"),
m_maincpu(*this, "maincpu"),
m_subcpu(*this, "subcpu"),
m_soundcpu(*this, "soundcpu"),
m_i8255(*this, "i8255"),
m_nvram(*this, "nvram"),
m_sprites(*this, "sprites"),
m_segaic16vid(*this, "segaic16vid"),
m_segaic16road(*this, "segaic16road"),
m_workram(*this, "workram"),
m_custom_map(NULL),
m_shangon_video(false),
m_scanline_timer(NULL),
m_irq2_state(0),
m_adc_select(0),
m_vblank_irq_state(0)
{ }
// PPI read/write handlers
@ -49,6 +49,8 @@ public:
DECLARE_WRITE8_MEMBER( unknown_porta_w );
DECLARE_WRITE8_MEMBER( unknown_portb_w );
DECLARE_WRITE8_MEMBER( video_control_w );
DECLARE_READ8_MEMBER( bankmotor_limit_r );
DECLARE_WRITE8_MEMBER( bankmotor_pos_w );
// memory mapping
void memory_mapper(sega_315_5195_mapper_device &mapper, UINT8 index);