(MESS) nes.c: emulated microphone input for old famicom controller,

as detected by games (i.e. it only detects voice/no voice, while the actual 
transmission of your voice to the speakers is not emulated). To use it in 
games expecting you to blow or shout in the mic, select the "Gamepad 
(Older Version)" as "P2 Controller" in the Driver Configuration submenu, 
and press "6" when the game requires it. [Fabio Priuli]

input is recognized both by BASIC (peeking at $4016) and by Raid on Bungeling Bay 2P mode, so I think it's correct...
This commit is contained in:
Fabio Priuli 2013-06-15 18:04:29 +00:00
parent e85a6675c9
commit ce7fd3a5d4
3 changed files with 48 additions and 24 deletions

View File

@ -184,6 +184,14 @@ static INPUT_PORTS_START( fc_pads12 )
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010)
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Microphone") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x00f0)
INPUT_PORTS_END
@ -523,6 +531,7 @@ static INPUT_PORTS_START( famicom )
PORT_CONFSETTING( 0x0000, "Unconnected" )
PORT_CONFSETTING( 0x0010, "Gamepad" )
PORT_CONFSETTING( 0x0020, "Crazy Climber pad (Right)" )
PORT_CONFSETTING( 0x00f0, "Gamepad (Older Version)" )
PORT_CONFNAME( 0x0f00, 0x0000, "P3 Controller") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07)
PORT_CONFSETTING( 0x0000, "Unconnected" )
PORT_CONFSETTING( 0x0100, "Gamepad" )

View File

@ -512,6 +512,7 @@ public:
DECLARE_READ8_MEMBER(psg_4015_r);
DECLARE_WRITE8_MEMBER(psg_4015_w);
DECLARE_WRITE8_MEMBER(psg_4017_w);
void state_register();
/***** FDS-floppy related *****/
@ -551,11 +552,13 @@ public:
void fds_irq(int scanline, int vblank, int blanked);
// input related
UINT32 m_pad_latch[4];
UINT8 m_zapper_latch[2][3];
UINT8 m_paddle_latch, m_paddle_btn_latch;
UINT8 m_mjpanel_latch;
UINT8 m_fck_scan, m_fck_mode;
UINT8 m_mic_obstruct;
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);

View File

@ -51,33 +51,34 @@ void nes_state::machine_reset()
m_paddle_btn_latch = 0;
}
static void nes_state_register( running_machine &machine )
void nes_state::state_register()
{
nes_state *state = machine.driver_data<nes_state>();
save_item(NAME(m_last_frame_flip));
state->save_item(NAME(state->m_last_frame_flip));
save_item(NAME(m_fds_motor_on));
save_item(NAME(m_fds_door_closed));
save_item(NAME(m_fds_current_side));
save_item(NAME(m_fds_head_position));
save_item(NAME(m_fds_status0));
save_item(NAME(m_fds_read_mode));
save_item(NAME(m_fds_write_reg));
save_item(NAME(m_fds_last_side));
save_item(NAME(m_fds_count));
save_item(NAME(m_fds_mirroring));
state->save_item(NAME(state->m_fds_motor_on));
state->save_item(NAME(state->m_fds_door_closed));
state->save_item(NAME(state->m_fds_current_side));
state->save_item(NAME(state->m_fds_head_position));
state->save_item(NAME(state->m_fds_status0));
state->save_item(NAME(state->m_fds_read_mode));
state->save_item(NAME(state->m_fds_write_reg));
state->save_item(NAME(state->m_fds_last_side));
state->save_item(NAME(state->m_fds_count));
state->save_item(NAME(state->m_fds_mirroring));
save_pointer(NAME(m_ciram), 0x800);
state->save_pointer(NAME(state->m_ciram), 0x800);
if (m_disk_expansion)
save_pointer(NAME(m_vram), 0x800);
if (state->m_disk_expansion)
state->save_pointer(NAME(state->m_vram), 0x800);
state->save_item(NAME(state->m_pad_latch));
state->save_item(NAME(state->m_zapper_latch));
state->save_item(NAME(state->m_paddle_latch));
state->save_item(NAME(state->m_paddle_btn_latch));
state->save_item(NAME(state->m_mjpanel_latch));
save_item(NAME(m_pad_latch));
save_item(NAME(m_zapper_latch));
save_item(NAME(m_paddle_latch));
save_item(NAME(m_paddle_btn_latch));
save_item(NAME(m_mjpanel_latch));
save_item(NAME(m_fck_scan));
save_item(NAME(m_fck_mode));
save_item(NAME(m_mic_obstruct));
}
@ -197,7 +198,7 @@ void nes_state::machine_start()
membank("fdsram")->set_base(m_fds_ram);
}
nes_state_register(machine());
state_register();
}
@ -374,6 +375,7 @@ WRITE8_MEMBER(nes_state::nes_in1_w)
READ8_MEMBER(nes_state::fc_in0_r)
{
int cfg = m_io_ctrlsel->read();
int exp = m_io_exp->read();
// Some games expect bit 6 to be set because the last entry on the data bus shows up
@ -383,7 +385,11 @@ READ8_MEMBER(nes_state::fc_in0_r)
// shift
m_pad_latch[0] >>= 1;
// microphone bit
if ((cfg & 0x00f0) == 0x00f0)
ret |= m_mic_obstruct; //bit2!
// EXP input
switch (exp & 0x0f)
{
@ -542,6 +548,7 @@ WRITE8_MEMBER(nes_state::fc_in0_w)
m_paddle_btn_latch = 0;
m_paddle_latch = 0;
m_mjpanel_latch = 0;
m_mic_obstruct = 0;
// P1 inputs
switch (cfg & 0x000f)
@ -566,6 +573,11 @@ WRITE8_MEMBER(nes_state::fc_in0_w)
m_pad_latch[1] = m_io_cc_right->read();
break;
case 0x0f: // pad 2 old style with microphone instead of START/SELECT keys
// we only emulate obstruction of mic (when you blow or talk into it)
m_mic_obstruct = m_io_pad[1]->read() & 0x04;
m_pad_latch[1] = (m_io_pad[1]->read() & ~0x04);
break;
}
// P3 & P4 inputs in Famicom (e.g. through Hori Twin Adapter or Hori 4 Players Adapter)