diff options
37 files changed, 3822 insertions, 1196 deletions
diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak index 0c6f5484174..21f071394bb 100644 --- a/src/emu/bus/bus.mak +++ b/src/emu/bus/bus.mak @@ -1087,6 +1087,31 @@ endif #------------------------------------------------- # +#@src/emu/bus/nes_ctrl/ctrl.h,BUSES += NES_CTRL +#------------------------------------------------- + +ifneq ($(filter NES_CTRL,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/nes_ctrl +BUSOBJS += $(BUSOBJ)/nes_ctrl/ctrl.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/joypad.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/4score.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/arkpaddle.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/bcbattle.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/ftrainer.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/fckeybrd.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/hori.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/konamihs.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/miracle.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/mjpanel.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/pachinko.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/partytap.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/powerpad.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/suborkey.o +BUSOBJS += $(BUSOBJ)/nes_ctrl/zapper.o +endif + +#------------------------------------------------- +# #@src/emu/bus/snes/snes_slot.h,BUSES += SNES #------------------------------------------------- diff --git a/src/emu/bus/nes_ctrl/4score.c b/src/emu/bus/nes_ctrl/4score.c new file mode 100644 index 00000000000..ef384855612 --- /dev/null +++ b/src/emu/bus/nes_ctrl/4score.c @@ -0,0 +1,190 @@ +/********************************************************************** + + Nintendo Entertainment System Four Score Adapter + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + + + TODO: current implementation is a HACK, due to limitations of the + slot system! + A real Four Score would be connected to both the controller ports of + the NES, but current core cannot emulate something like this until + devices can live their own life and being connected to other devices + at request. + In current implementation the device has to be mounted separately in + the two ports and each enables 2 inputs (this is more or less as hacky + as the non-slot previous one, where the 4 ports were always available + to the emulated system, but it's not a great consolation :( ) + Two subdevices are currently used so to warn the user that the first + one gives P1+P3 inputs and the second one gives P2+P4 inputs. + For the same reason, we don't currently emulate the 2P/4P switch, + since we could at best have two switches to disable the second player + inputs. + + Note: Two Pads are hardcoded in inputs below, instead of acting as + passthrough for 2 standard joypad devices, in order to show in the + internal UI that they belong to P1+P3 and P2+P4, otherwise they would + be listed as P1+P2 and P3+P4 respectively. This *HAS* to be changed + once the slot support in the code has improved (4 standard joypads + shall be attached to the unit!) + +**********************************************************************/ + +#include "4score.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_4SCORE_P1P3 = &device_creator<nes_4score_p1p3_device>; +const device_type NES_4SCORE_P2P4 = &device_creator<nes_4score_p2p4_device>; + + +static INPUT_PORTS_START( nes_4score_p1p3 ) + PORT_START("PAD1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") PORT_PLAYER(1) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") PORT_PLAYER(1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(1) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) + + PORT_START("PAD3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") PORT_PLAYER(3) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") PORT_PLAYER(3) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(3) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(3) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(3) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) +INPUT_PORTS_END + + +static INPUT_PORTS_START( nes_4score_p2p4 ) + PORT_START("PAD2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) + + PORT_START("PAD4") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") PORT_PLAYER(4) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") PORT_PLAYER(4) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(4) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(4) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(4) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_4score_p1p3_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_4score_p1p3 ); +} + +ioport_constructor nes_4score_p2p4_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_4score_p2p4 ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_4score_device - constructor +//------------------------------------------------- + +nes_4score_device::nes_4score_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_nes_control_port_interface(mconfig, *this) +{ +} + +nes_4score_p1p3_device::nes_4score_p1p3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + nes_4score_device(mconfig, NES_4SCORE_P1P3, "Nintendo Four Score Adapter P1/P3", tag, owner, clock, "nes_4score_p1p3", __FILE__), + m_joypad1(*this, "PAD1"), + m_joypad3(*this, "PAD3") +{ +} + +nes_4score_p2p4_device::nes_4score_p2p4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + nes_4score_device(mconfig, NES_4SCORE_P2P4, "Nintendo Four Score Adapter P2/P4", tag, owner, clock, "nes_4score_p2p4", __FILE__), + m_joypad2(*this, "PAD2"), + m_joypad4(*this, "PAD4") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_4score_device::device_start() +{ + save_item(NAME(m_latch)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_4score_device::device_reset() +{ + m_latch = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_4score_device::read_bit0() +{ + UINT8 ret = m_latch & 1; + m_latch >>= 1; + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_4score_p1p3_device::write(UINT8 data) +{ + if (data & 0x01) + return; + + // P3 & P4 inputs in NES Four Score are read serially with P1 & P2 + m_latch = m_joypad1->read(); + m_latch |= (m_joypad3->read() << 8); // pad 3 + m_latch |= (0x08 << 16); // signature +} + +void nes_4score_p2p4_device::write(UINT8 data) +{ + if (data & 0x01) + return; + + // P3 & P4 inputs in NES Four Score are read serially with P1 & P2 + m_latch = m_joypad2->read(); + m_latch |= (m_joypad4->read() << 8); // pad 4 + m_latch |= (0x04 << 16); // signature +} diff --git a/src/emu/bus/nes_ctrl/4score.h b/src/emu/bus/nes_ctrl/4score.h new file mode 100644 index 00000000000..f7a688fb162 --- /dev/null +++ b/src/emu/bus/nes_ctrl/4score.h @@ -0,0 +1,85 @@ +/********************************************************************** + + Nintendo Entertainment System Four Score Adapter + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_FOURSCORE__ +#define __NES_FOURSCORE__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_4score_device + +class nes_4score_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_4score_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_bit0(); + +protected: + UINT32 m_latch; +}; + +// ======================> nes_4score_p1p3_device + +class nes_4score_p1p3_device : public nes_4score_device +{ +public: + // construction/destruction + nes_4score_p1p3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + virtual void write(UINT8 data); + +private: + required_ioport m_joypad1; + required_ioport m_joypad3; +}; + +// ======================> nes_4score_p2p4_device + +class nes_4score_p2p4_device : public nes_4score_device +{ +public: + // construction/destruction + nes_4score_p2p4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + virtual void write(UINT8 data); + +private: + required_ioport m_joypad2; + required_ioport m_joypad4; +}; + + +// device type definition +extern const device_type NES_4SCORE_P1P3; +extern const device_type NES_4SCORE_P2P4; + + +#endif diff --git a/src/emu/bus/nes_ctrl/arkpaddle.c b/src/emu/bus/nes_ctrl/arkpaddle.c new file mode 100644 index 00000000000..61dd183603c --- /dev/null +++ b/src/emu/bus/nes_ctrl/arkpaddle.c @@ -0,0 +1,131 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System - + Arkanoid Paddle input device + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "arkpaddle.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_ARKPADDLE = &device_creator<nes_vaus_device>; +const device_type NES_ARKPADDLE_FC = &device_creator<nes_vausfc_device>; + + +static INPUT_PORTS_START( arkanoid_paddle ) + PORT_START("PADDLE") + PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) PORT_CENTERDELTA(0) PORT_MINMAX(0x62,0xf2) + PORT_START("BUTTON") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Paddle button") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_vaus_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( arkanoid_paddle ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_vaus_device - constructor +//------------------------------------------------- + +nes_vaus_device::nes_vaus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_nes_control_port_interface(mconfig, *this), + m_paddle(*this, "PADDLE"), + m_button(*this, "BUTTON") +{ +} + +nes_vaus_device::nes_vaus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_ARKPADDLE, "Arkanoid Vaus NES Controller", tag, owner, clock, "nes_vaus", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_paddle(*this, "PADDLE"), + m_button(*this, "BUTTON") +{ +} + +nes_vausfc_device::nes_vausfc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + nes_vaus_device(mconfig, NES_ARKPADDLE_FC, "Arkanoid Vaus FC Controller", tag, owner, clock, "nes_vausfc", __FILE__) +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_vaus_device::device_start() +{ + save_item(NAME(m_latch)); + save_item(NAME(m_start_conv)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_vaus_device::device_reset() +{ + m_latch = 0; + m_start_conv = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_vaus_device::read_bit34() +{ + UINT8 ret = (m_button->read() << 3); + ret |= (m_latch & 0x80) >> 3; + m_latch <<= 1; + m_latch &= 0xff; + return ret; +} + +UINT8 nes_vausfc_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 0) //$4016 + ret = m_button->read() << 1; + else //$4017 + { + ret = (m_latch & 0x80) >> 6; + m_latch <<= 1; + m_latch &= 0xff; + } + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_vaus_device::write(UINT8 data) +{ + int old = m_start_conv; + + if (data == 0 && old == 1) + m_latch = (UINT8) (m_paddle->read() ^ 0xff); + + m_start_conv = data; +} diff --git a/src/emu/bus/nes_ctrl/arkpaddle.h b/src/emu/bus/nes_ctrl/arkpaddle.h new file mode 100644 index 00000000000..a683f3e9904 --- /dev/null +++ b/src/emu/bus/nes_ctrl/arkpaddle.h @@ -0,0 +1,71 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System - + Arkanoid Paddle input device + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_ARKPADDLE__ +#define __NES_ARKPADDLE__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_vaus_device + +class nes_vaus_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_vaus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + nes_vaus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_bit34(); + virtual void write(UINT8 data); + + required_ioport m_paddle; + required_ioport m_button; + UINT8 m_start_conv; + UINT32 m_latch; +}; + + +// ======================> nes_vaus_device + +class nes_vausfc_device : public nes_vaus_device +{ +public: + // construction/destruction + nes_vausfc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + virtual UINT8 read_bit34() { return 0; } + virtual UINT8 read_exp(offs_t offset); +}; + + +// device type definition +extern const device_type NES_ARKPADDLE; +extern const device_type NES_ARKPADDLE_FC; + + +#endif diff --git a/src/emu/bus/nes_ctrl/bcbattle.c b/src/emu/bus/nes_ctrl/bcbattle.c new file mode 100644 index 00000000000..403bdeec1ae --- /dev/null +++ b/src/emu/bus/nes_ctrl/bcbattle.c @@ -0,0 +1,193 @@ +/********************************************************************** + + Nintendo Family Computer - Epoch Barcode Battler + + TODO: this should be actually emulated as a standalone system with + a few 7segments LEDs, once we get a dump of its BIOS + At the moment we only emulated the connection with a Famicom + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "bcbattle.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_BARCODE_BATTLER = &device_creator<nes_bcbattle_device>; + + +static INPUT_PORTS_START( nes_battler ) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_bcbattle_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_battler ); +} + +MACHINE_CONFIG_FRAGMENT( nes_battler ) + MCFG_BARCODE_READER_ADD("battler") +MACHINE_CONFIG_END + +machine_config_constructor nes_bcbattle_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( nes_battler ); +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void nes_bcbattle_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (id == TIMER_BATTLER) + { + int old = m_new_code; + // has something new been scanned? + if (old < m_reader->get_pending_code()) + { + if (m_reader->get_byte_length() == 13) + { + for (int i = 0; i < 13; i++) + m_current_barcode[i] = m_reader->read_code() + '0'; + } + else if (m_reader->get_byte_length() == 8) + { + for (int i = 0; i < 5; i++) + m_current_barcode[i] = 0x20; + for (int i = 5; i < 13; i++) + m_current_barcode[i] = m_reader->read_code() + '0'; + } + // read one more, to reset the internal byte counter + m_reader->read_code(); + + // the string "SUNSOFT" is accepted as well by Barcode World + m_current_barcode[13] = 'E'; + m_current_barcode[14] = 'P'; + m_current_barcode[15] = 'O'; + m_current_barcode[16] = 'C'; + m_current_barcode[17] = 'H'; + m_current_barcode[18] = 0x0d; + m_current_barcode[19] = 0x0a; + m_pending_code = 1; + } + m_new_code = m_reader->get_pending_code(); + } +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_bcbattle_device - constructor +//------------------------------------------------- + +nes_bcbattle_device::nes_bcbattle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_BARCODE_BATTLER, "Epoch Barcode Battler", tag, owner, clock, "nes_bcbattle", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_reader(*this, "battler") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_bcbattle_device::device_start() +{ + // lacking emulation of the standalone Barcode Battler, we refresh periodically the input from the reader + // proper emulation would have the standalone unit acknowledging that a new barcode has been scanned + // and sending the proper serial bits, instead of our read_current_bit() function! + battler_timer = timer_alloc(TIMER_BATTLER); + battler_timer->adjust(attotime::zero, 0, machine().device<cpu_device>("maincpu")->cycles_to_attotime(1000)); + + save_item(NAME(m_current_barcode)); + save_item(NAME(m_new_code)); + save_item(NAME(m_pending_code)); + save_item(NAME(m_transmitting)); + save_item(NAME(m_cur_bit)); + save_item(NAME(m_cur_byte)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_bcbattle_device::device_reset() +{ + m_pending_code = 0; + m_new_code = 0; + m_transmitting = 0; + m_cur_bit = 0; + m_cur_byte = 0; + memset(m_current_barcode, 0, ARRAY_LENGTH(m_current_barcode)); +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +int nes_bcbattle_device::read_current_bit() +{ + if (m_pending_code && !m_transmitting) + { + // we start with 1 + m_transmitting = 1; + m_cur_byte = 0; + m_cur_bit = 0; + return 1; + } + + if (m_transmitting) + { + if (m_cur_bit == 0) + { + m_cur_bit++; + return 1; + } + if (m_cur_bit < 9) + { + int bit = (BIT(m_current_barcode[m_cur_byte], m_cur_bit - 1)) ^ 1; + m_cur_bit++; + return bit; + } + if (m_cur_bit == 9) + { + m_cur_bit = 0; + //printf("%X ", m_current_barcode[m_cur_byte]); + m_cur_byte++; + if (m_cur_byte == 20) + { + m_cur_byte = 0; + m_transmitting = 0; + m_pending_code = 0; + } + return 0; + } + } + + return 0; +} + +UINT8 nes_bcbattle_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 1) //$4017 + { + ret |= read_current_bit() << 2; + } + + return ret; +} diff --git a/src/emu/bus/nes_ctrl/bcbattle.h b/src/emu/bus/nes_ctrl/bcbattle.h new file mode 100644 index 00000000000..c38c8d54c1b --- /dev/null +++ b/src/emu/bus/nes_ctrl/bcbattle.h @@ -0,0 +1,55 @@ +/********************************************************************** + + Nintendo Family Computer - Epoch Barcode Battler + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_BCBATTLE__ +#define __NES_BCBATTLE__ + + +#include "emu.h" +#include "ctrl.h" +#include "machine/bcreader.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_bcbattle_device + +class nes_bcbattle_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_bcbattle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + int read_current_bit(); + + static const device_timer_id TIMER_BATTLER = 1; + required_device<barcode_reader_device> m_reader; + UINT8 m_current_barcode[20]; + int m_pending_code, m_new_code, m_transmitting, m_cur_bit, m_cur_byte; + emu_timer *battler_timer; +}; + +// device type definition +extern const device_type NES_BARCODE_BATTLER; + +#endif diff --git a/src/emu/bus/nes_ctrl/ctrl.c b/src/emu/bus/nes_ctrl/ctrl.c new file mode 100644 index 00000000000..c90b2bf82e5 --- /dev/null +++ b/src/emu/bus/nes_ctrl/ctrl.c @@ -0,0 +1,208 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System controller ports + and Family Computer expansion port emulation + + Here we emulate in fact 3 different kind of ports, which are + connected to different bis of memory locations $4016 and $4017: + - NES controller ports: these are hooked to bit 0,3,4 of the + corresponding address ($4016 for port1, $4017 for port2) + - FC controller ports: these are only hooked to bit 0 of the + corresponding address (so that e.g. a NES Zapper could not + be connected to a later FC AV model, because its inputs + would not be detected) + - FC expansion port: this is hooked to bits 0-4 of both addresses + To make things a little bit more complex, old FC models have the + controller hardwired to the unit, and the P2 controllers are + directly hooked also to one of the expansion port lines (namely, + microphone inputs from P2 go to $4016 bit 2) + + Even if the controller port and the expansion port are + physically different (the FC expansion is a 15pin port, while + the controller ports are 7pin), we emulate them as variants of a + common device, exposing the following handlers: + - read_bit0: for bit0 reads, which are typically used for serial + inputs from controllers + - read_bit34: for bit3,4 reading, expected to be at the correct + offset (but we don't currently check for read_bit34 & 0xf8==0) + - read_exp: for reads going through the expansion, with a offset + parameter to decide whether we are reading from $4016 and $4017 + - write: to acknowledge writes to $4016 + + The driver emulation will take care to only call the correct + handlers they have hooks for: Basic usage is that the expansion + port calls read_exp, FC ctrl ports call read_bit0, and NES ctrl + ports call both read_bit0 and read_bit34. However, to cope with + the original FC microphone, we will have the second controller + port calling read_exp too. + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "ctrl.h" +// slot devices +#include "4score.h" +#include "arkpaddle.h" +#include "bcbattle.h" +#include "ftrainer.h" +#include "fckeybrd.h" +#include "hori.h" +#include "joypad.h" +#include "konamihs.h" +#include "miracle.h" +#include "mjpanel.h" +#include "pachinko.h" +#include "partytap.h" +#include "powerpad.h" +#include "suborkey.h" +#include "zapper.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type NES_CONTROL_PORT = &device_creator<nes_control_port_device>; + + + +//************************************************************************** +// CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_nes_control_port_interface - constructor +//------------------------------------------------- + +device_nes_control_port_interface::device_nes_control_port_interface(const machine_config &mconfig, device_t &device) : + device_slot_card_interface(mconfig, device) +{ + m_port = dynamic_cast<nes_control_port_device *>(device.owner()); +} + + +//------------------------------------------------- +// ~device_nes_control_port_interface - destructor +//------------------------------------------------- + +device_nes_control_port_interface::~device_nes_control_port_interface() +{ +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_control_port_device - constructor +//------------------------------------------------- + +nes_control_port_device::nes_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_CONTROL_PORT, "Nintendo NES/FC control port", tag, owner, clock, "nes_control_port", __FILE__), + device_slot_interface(mconfig, *this) +{ +} + + +//------------------------------------------------- +// nes_control_port_device - destructor +//------------------------------------------------- + +nes_control_port_device::~nes_control_port_device() +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void nes_control_port_device::device_start() +{ + m_device = dynamic_cast<device_nes_control_port_interface *>(get_card_device()); + m_brightpixel_cb.bind_relative_to(*owner()); +} + + +UINT8 nes_control_port_device::read_bit0() +{ + UINT8 data = 0; + if (m_device) + data = m_device->read_bit0(); + return data; +} + +UINT8 nes_control_port_device::read_bit34() +{ + UINT8 data = 0; + if (m_device) + data = m_device->read_bit34(); + return data; +} + +UINT8 nes_control_port_device::read_exp(offs_t offset) +{ + UINT8 data = 0; + if (m_device) + data = m_device->read_exp(offset); + return data; +} + +void nes_control_port_device::write(UINT8 data) +{ + if (m_device) + m_device->write(data); +} + + + +//------------------------------------------------- +// SLOT_INTERFACE( nes_control_port_devices ) +//------------------------------------------------- + +SLOT_INTERFACE_START( nes_control_port1_devices ) + SLOT_INTERFACE("joypad", NES_JOYPAD) + SLOT_INTERFACE("zapper", NES_ZAPPER) + SLOT_INTERFACE("4score_p1p3", NES_4SCORE_P1P3) +// SLOT_INTERFACE("miracle_piano", NES_MIRACLE) +SLOT_INTERFACE_END + +SLOT_INTERFACE_START( nes_control_port2_devices ) + SLOT_INTERFACE("joypad", NES_JOYPAD) + SLOT_INTERFACE("zapper", NES_ZAPPER) + SLOT_INTERFACE("vaus", NES_ARKPADDLE) + SLOT_INTERFACE("powerpad", NES_POWERPAD) + SLOT_INTERFACE("4score_p2p4", NES_4SCORE_P2P4) +SLOT_INTERFACE_END + +SLOT_INTERFACE_START( fc_control_port1_devices ) + SLOT_INTERFACE("joypad", NES_JOYPAD) + SLOT_INTERFACE("ccpad_left", NES_CCPAD_LEFT) +SLOT_INTERFACE_END + +SLOT_INTERFACE_START( fc_control_port2_devices ) + SLOT_INTERFACE("joypad", NES_JOYPAD) + SLOT_INTERFACE("joypad_old", NES_FCPAD_P2) + SLOT_INTERFACE("ccpad_right", NES_CCPAD_RIGHT) +SLOT_INTERFACE_END + +SLOT_INTERFACE_START( fc_expansion_devices ) + SLOT_INTERFACE("joypad", NES_JOYPAD) + SLOT_INTERFACE("arcstick", NES_ARCSTICK) + SLOT_INTERFACE("fc_keyboard", NES_FCKEYBOARD) + SLOT_INTERFACE("zapper", NES_ZAPPER) + SLOT_INTERFACE("vaus", NES_ARKPADDLE_FC) + SLOT_INTERFACE("family_trainer", NES_FTRAINER) + SLOT_INTERFACE("konamihs", NES_KONAMIHS) + SLOT_INTERFACE("mj_panel", NES_MJPANEL) + SLOT_INTERFACE("pachinko", NES_PACHINKO) + SLOT_INTERFACE("partytap", NES_PARTYTAP) + SLOT_INTERFACE("hori_twin", NES_HORITWIN) + SLOT_INTERFACE("hori_4p", NES_HORI4P) + SLOT_INTERFACE("barcode_battler", NES_BARCODE_BATTLER) + SLOT_INTERFACE("subor_keyboard", NES_SUBORKEYBOARD) +SLOT_INTERFACE_END diff --git a/src/emu/bus/nes_ctrl/ctrl.h b/src/emu/bus/nes_ctrl/ctrl.h new file mode 100644 index 00000000000..a87b3c9dc9f --- /dev/null +++ b/src/emu/bus/nes_ctrl/ctrl.h @@ -0,0 +1,104 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System controller port + emulation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +********************************************************************** + + +**********************************************************************/ + +#pragma once + +#ifndef __NES_CONTROL_PORT__ +#define __NES_CONTROL_PORT__ + +#include "emu.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class nes_control_port_device; + +// ======================> device_nes_control_port_interface + +class device_nes_control_port_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_nes_control_port_interface(const machine_config &mconfig, device_t &device); + virtual ~device_nes_control_port_interface(); + + virtual UINT8 read_bit0() { return 0; }; + virtual UINT8 read_bit34() { return 0; }; + virtual UINT8 read_exp(offs_t offset) { return 0; }; + virtual void write(UINT8 data) { }; + +protected: + nes_control_port_device *m_port; +}; + + +typedef device_delegate<bool (int x, int y)> nesctrl_brightpixel_delegate; +#define NESCTRL_BRIGHTPIXEL_CB(name) bool name(int x, int y) + + +// ======================> nes_control_port_device + +class nes_control_port_device : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + nes_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~nes_control_port_device(); + + static void set_brightpixel_callback(device_t &device, nesctrl_brightpixel_delegate callback) { downcast<nes_control_port_device &>(device).m_brightpixel_cb = callback; } + + UINT8 read_bit0(); + UINT8 read_bit34(); + UINT8 read_exp(offs_t offset); + void write(UINT8 data); + + nesctrl_brightpixel_delegate m_brightpixel_cb; + +protected: + // device-level overrides + virtual void device_start(); + device_nes_control_port_interface *m_device; +}; + + +// device type definition +extern const device_type NES_CONTROL_PORT; + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_NES_CONTROL_PORT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, NES_CONTROL_PORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + +// currently this is emulated as a control port... +#define MCFG_FC_EXPANSION_PORT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, NES_CONTROL_PORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + +#define MCFG_NESCTRL_BRIGHTPIXEL_CB(_class, _method) \ + nes_control_port_device::set_brightpixel_callback(*device, nesctrl_brightpixel_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); + + +SLOT_INTERFACE_EXTERN( nes_control_port1_devices ); +SLOT_INTERFACE_EXTERN( nes_control_port2_devices ); +SLOT_INTERFACE_EXTERN( fc_control_port1_devices ); +SLOT_INTERFACE_EXTERN( fc_control_port2_devices ); +SLOT_INTERFACE_EXTERN( fc_expansion_devices ); + + +#endif diff --git a/src/emu/bus/nes_ctrl/fckeybrd.c b/src/emu/bus/nes_ctrl/fckeybrd.c new file mode 100644 index 00000000000..f31fc04e848 --- /dev/null +++ b/src/emu/bus/nes_ctrl/fckeybrd.c @@ -0,0 +1,232 @@ +/********************************************************************** + + Nintendo Family Computer Keyboard Component + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "fckeybrd.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_FCKEYBOARD = &device_creator<nes_fckeybrd_device>; + + +static INPUT_PORTS_START( fc_keyboard ) + PORT_START("FCKEY.0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Kana") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('\\') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Stop") PORT_CODE(KEYCODE_BACKSPACE) + + PORT_START("FCKEY.1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('_') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('/') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') + + PORT_START("FCKEY.2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + + PORT_START("FCKEY.3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') + + PORT_START("FCKEY.4") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') + + PORT_START("FCKEY.5") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + + PORT_START("FCKEY.6") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') + + PORT_START("FCKEY.7") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Grph") PORT_CODE(KEYCODE_LALT) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + + PORT_START("FCKEY.8") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Clr") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ins") PORT_CODE(KEYCODE_INSERT) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_fckeybrd_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( fc_keyboard ); +} + + +static MACHINE_CONFIG_FRAGMENT( fc_keyboard ) + MCFG_CASSETTE_ADD("tape") + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) + MCFG_CASSETTE_INTERFACE("fc_cass") +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor nes_fckeybrd_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( fc_keyboard ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_fckeybrd_device - constructor +//------------------------------------------------- + +nes_fckeybrd_device::nes_fckeybrd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_FCKEYBOARD, "Nintendo Family Computer Keyboard Component", tag, owner, clock, "nes_fckeybrd", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_cassette(*this, "tape"), + m_kbd(*this, "FCKEY") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_fckeybrd_device::device_start() +{ + save_item(NAME(m_fck_scan)); + save_item(NAME(m_fck_mode)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_fckeybrd_device::device_reset() +{ + m_fck_scan = 0; + m_fck_mode = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_fckeybrd_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 0) //$4016 + { + // FC Keyboard: tape input + if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) + { + double level = m_cassette->input(); + if (level < 0) + ret |= 0x00; + else + ret |= 0x02; + } + } + else //$4017 + { + // FC Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 + if (m_fck_scan < 9) + ret |= ~(((m_kbd[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; + else + ret |= 0x1e; + } + + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_fckeybrd_device::write(UINT8 data) +{ + // tape output (not fully tested) + if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD) + m_cassette->output(((data & 0x07) == 0x07) ? +1.0 : -1.0); + + if (BIT(data, 2)) // keyboard active + { + UINT8 out = BIT(data, 1); // scan + + if (m_fck_mode && !out && ++m_fck_scan > 9) + m_fck_scan = 0; + + m_fck_mode = out; // access lower or upper 4 bits + + if (BIT(data, 0)) // reset + m_fck_scan = 0; + } +} diff --git a/src/emu/bus/nes_ctrl/fckeybrd.h b/src/emu/bus/nes_ctrl/fckeybrd.h new file mode 100644 index 00000000000..df265370fff --- /dev/null +++ b/src/emu/bus/nes_ctrl/fckeybrd.h @@ -0,0 +1,55 @@ +/********************************************************************** + + Nintendo Family Computer Keyboard Component + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_FCKEYBRD__ +#define __NES_FCKEYBRD__ + + +#include "emu.h" +#include "ctrl.h" +#include "imagedev/cassette.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_fckeybrd_device + +class nes_fckeybrd_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_fckeybrd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + +private: + required_device<cassette_image_device> m_cassette; + required_ioport_array<9> m_kbd; + UINT8 m_fck_scan, m_fck_mode; +}; + + +// device type definition +extern const device_type NES_FCKEYBOARD; + + +#endif diff --git a/src/emu/bus/nes_ctrl/ftrainer.c b/src/emu/bus/nes_ctrl/ftrainer.c new file mode 100644 index 00000000000..38fdc326ed6 --- /dev/null +++ b/src/emu/bus/nes_ctrl/ftrainer.c @@ -0,0 +1,154 @@ +/********************************************************************** + + Nintendo Family Computer - Bandai Family Trainer Mat + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "ftrainer.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_FTRAINER = &device_creator<nes_ftrainer_device>; + + +static INPUT_PORTS_START( nes_joypad ) + PORT_START("LAYOUT") + PORT_CONFNAME( 0x01, 0x00, "Family Trainer Button Layout") + PORT_CONFSETTING( 0x00, "Side A" ) + PORT_CONFSETTING( 0x01, "Side B" ) + + // difference between the two sides is that we mirror the key mapping to match the real pad layout! + PORT_START("FT_COL.0") + // side A layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid1") PORT_CODE(KEYCODE_J) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + // side B layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 12") PORT_CODE(KEYCODE_M) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 8") PORT_CODE(KEYCODE_J) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 4") PORT_CODE(KEYCODE_U) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + + PORT_START("FT_COL.1") + // side A layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Low1") PORT_CODE(KEYCODE_N) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid2") PORT_CODE(KEYCODE_H) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Top1") PORT_CODE(KEYCODE_Y) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + // side B layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 11") PORT_CODE(KEYCODE_N) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 7") PORT_CODE(KEYCODE_H) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 3") PORT_CODE(KEYCODE_Y) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + + PORT_START("FT_COL.2") + // side A layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Low2") PORT_CODE(KEYCODE_B) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid3") PORT_CODE(KEYCODE_G) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Top2") PORT_CODE(KEYCODE_T) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + // side B layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 10") PORT_CODE(KEYCODE_B) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 6") PORT_CODE(KEYCODE_G) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 2") PORT_CODE(KEYCODE_T) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + + PORT_START("FT_COL.3") + // side A layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid4") PORT_CODE(KEYCODE_F) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + // side B layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 9") PORT_CODE(KEYCODE_V) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 5") PORT_CODE(KEYCODE_F) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 1") PORT_CODE(KEYCODE_R) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_ftrainer_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_joypad ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_ftrainer_device - constructor +//------------------------------------------------- + +nes_ftrainer_device::nes_ftrainer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_FTRAINER, "Bandai Family Trainer", tag, owner, clock, "nes_famtrain", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_trainer(*this, "FT_COL") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_ftrainer_device::device_start() +{ + save_item(NAME(m_row_scan)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_ftrainer_device::device_reset() +{ + m_row_scan = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_ftrainer_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 1) //$4017 + { + if (!BIT(m_row_scan, 0)) + { + // read low line: buttons 9,10,11,12 + for (int i = 0; i < 4; i++) + ret |= ((m_trainer[i]->read() & 0x01) << (1 + i)); + } + else if (!BIT(m_row_scan, 1)) + { + // read mid line: buttons 5,6,7,8 + for (int i = 0; i < 4; i++) + ret |= ((m_trainer[i]->read() & 0x02) << (1 + i)); + } + else if (!BIT(m_row_scan, 2)) + { + // read high line: buttons 1,2,3,4 + for (int i = 0; i < 4; i++) + ret |= ((m_trainer[i]->read() & 0x04) << (1 + i)); + } + } + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_ftrainer_device::write(UINT8 data) +{ + // select row to scan + m_row_scan = data & 0x07; +} diff --git a/src/emu/bus/nes_ctrl/ftrainer.h b/src/emu/bus/nes_ctrl/ftrainer.h new file mode 100644 index 00000000000..52c3ae0529c --- /dev/null +++ b/src/emu/bus/nes_ctrl/ftrainer.h @@ -0,0 +1,52 @@ +/********************************************************************** + + Nintendo Family Computer - Bandai Family Trainer Mat + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_FTRAINER__ +#define __NES_FTRAINER__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_ftrainer_device + +class nes_ftrainer_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_ftrainer_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + +private: + required_ioport_array<4> m_trainer; + UINT8 m_row_scan; +}; + + +// device type definition +extern const device_type NES_FTRAINER; + + +#endif diff --git a/src/emu/bus/nes_ctrl/hori.c b/src/emu/bus/nes_ctrl/hori.c new file mode 100644 index 00000000000..e9d48a98bf3 --- /dev/null +++ b/src/emu/bus/nes_ctrl/hori.c @@ -0,0 +1,169 @@ +/********************************************************************** + + Nintendo Family Computer Hori Twin (and 4P?) adapters + + Emulation of the 4Players adapter is quite pointless: if 2P mode + (default mode) it behaves like a Hori Twin adapter, in 4P mode + it has P1 and P2 inputs overwriting the inputs coming from the + main controllers (possibly creating a bit of confusion, since + you get 6 sets of inputs with only 4 acknowledged by the running + system). + For the moment we keep it available for documentation purposes. + + TODO: find out confirmation whether in 2P mode, inputs from joypads + connected to the 4players adapter are really seen as P3 and P4 inputs. + it seems the most reasonable setup (so that users with only 2 + external pads can use the adapter in 4P games), but one never knows... + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "hori.h" +#include "joypad.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_HORITWIN = &device_creator<nes_horitwin_device>; +const device_type NES_HORI4P = &device_creator<nes_hori4p_device>; + + +static INPUT_PORTS_START( nes_hori4p ) + PORT_START("CONFIG") + PORT_CONFNAME( 0x01, 0x00, "4 Players / 2 Players") + PORT_CONFSETTING( 0x00, "2 Players" ) + PORT_CONFSETTING( 0x01, "4 Players" ) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_hori4p_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_hori4p ); +} + + +static SLOT_INTERFACE_START( hori_adapter ) + SLOT_INTERFACE("joypad", NES_JOYPAD) +SLOT_INTERFACE_END + +static MACHINE_CONFIG_FRAGMENT( horitwin ) + MCFG_FC_EXPANSION_PORT_ADD("port1", hori_adapter, "joypad") + MCFG_FC_EXPANSION_PORT_ADD("port2", hori_adapter, "joypad") +MACHINE_CONFIG_END + +static MACHINE_CONFIG_FRAGMENT( hori4p ) + MCFG_FC_EXPANSION_PORT_ADD("port1", hori_adapter, "joypad") + MCFG_FC_EXPANSION_PORT_ADD("port2", hori_adapter, "joypad") + MCFG_FC_EXPANSION_PORT_ADD("port3", hori_adapter, "joypad") + MCFG_FC_EXPANSION_PORT_ADD("port4", hori_adapter, "joypad") +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor nes_horitwin_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( horitwin ); +} + +machine_config_constructor nes_hori4p_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( hori4p ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_horitwin_device - constructor +//------------------------------------------------- + +nes_horitwin_device::nes_horitwin_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_HORITWIN, "Hori Twin Adapter", tag, owner, clock, "nes_horitwin", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_port1(*this, "port1"), + m_port2(*this, "port2") +{ +} + +nes_hori4p_device::nes_hori4p_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_HORI4P, "Hori 4P Adapter", tag, owner, clock, "nes_hori4p", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_port1(*this, "port1"), + m_port2(*this, "port2"), + m_port3(*this, "port3"), + m_port4(*this, "port4"), + m_cfg(*this, "CONFIG") +{ +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_horitwin_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 0) //$4016 + ret |= (m_port1->read_bit0() << 1); + else //$4017 + ret |= (m_port2->read_bit0() << 1); + return ret; +} + +UINT8 nes_hori4p_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (m_cfg->read() == 0) // 2P + { + if (offset == 0) //$4016 + ret |= (m_port1->read_bit0() << 1); + else //$4017 + ret |= (m_port2->read_bit0() << 1); + } + else // 4P + { + if (offset == 0) //$4016 + { + ret |= (m_port1->read_bit0() << 0); + ret |= (m_port3->read_bit0() << 1); + } + else //$4017 + { + ret |= (m_port2->read_bit0() << 0); + ret |= (m_port4->read_bit0() << 1); + } + } + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_horitwin_device::write(UINT8 data) +{ + m_port1->write(data); + m_port2->write(data); +} + +void nes_hori4p_device::write(UINT8 data) +{ + m_port1->write(data); + m_port2->write(data); + m_port3->write(data); + m_port4->write(data); +} diff --git a/src/emu/bus/nes_ctrl/hori.h b/src/emu/bus/nes_ctrl/hori.h new file mode 100644 index 00000000000..15601a7cc8e --- /dev/null +++ b/src/emu/bus/nes_ctrl/hori.h @@ -0,0 +1,79 @@ +/********************************************************************** + + Nintendo Family Computer Hori Twin (and 4P?) adapters + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_HORI__ +#define __NES_HORI__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_horitwin_device + +class nes_horitwin_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_horitwin_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + // device-level overrides + virtual void device_start() {} + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + +private: + required_device<nes_control_port_device> m_port1; + required_device<nes_control_port_device> m_port2; +}; + +// ======================> nes_hori4p_device + +class nes_hori4p_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_hori4p_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + // device-level overrides + virtual void device_start() {} + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + +private: + required_device<nes_control_port_device> m_port1; + required_device<nes_control_port_device> m_port2; + required_device<nes_control_port_device> m_port3; + required_device<nes_control_port_device> m_port4; + required_ioport m_cfg; +}; + + +// device type definition +extern const device_type NES_HORITWIN; +extern const device_type NES_HORI4P; + + +#endif diff --git a/src/emu/bus/nes_ctrl/joypad.c b/src/emu/bus/nes_ctrl/joypad.c new file mode 100644 index 00000000000..2688e5e61e5 --- /dev/null +++ b/src/emu/bus/nes_ctrl/joypad.c @@ -0,0 +1,317 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System Joypads + + The original Famicom had two hardwired controller, with the second + controller slightly different from the first one: it featured no + Start nor Select buttons, but had a built-in microphone (with + very limited capabilities, since it basically only detected two + states: something blowing into it / nothing blowing into it) for + some games to react to users "talking" into it + + Crazy Climber Pads are not really a kind of separate controllers, + but just a couple of small sticks to be put on top of d-pads of + the regular controllers. Users should then control the game by + using both controllers, turned 90 degrees, as a couple of dual + sticks like in the arcade control panel. However, we emulate them + separately so to map the controls to a friendlier default. + + The Arcade Stick we emulate is a controller (apparently manufactured + by Hori, but possibly licensed by Nintendo, since it use the official + logo and brand) which fits into the expansion port and allows to + daisy chain a second controller to the first one, to play 4players + game (an image of such connection is shown e.g. in Nekketsu Koukou + Dodgeball Bu manual) + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "joypad.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_JOYPAD = &device_creator<nes_joypad_device>; +const device_type NES_FCPAD_P2 = &device_creator<nes_fcpad2_device>; +const device_type NES_CCPAD_LEFT = &device_creator<nes_ccpadl_device>; +const device_type NES_CCPAD_RIGHT = &device_creator<nes_ccpadr_device>; +const device_type NES_ARCSTICK = &device_creator<nes_arcstick_device>; + + +static INPUT_PORTS_START( nes_joypad ) + PORT_START("JOYPAD") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY +INPUT_PORTS_END + +static INPUT_PORTS_START( nes_fcpad_p2 ) + PORT_START("JOYPAD") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Microphone") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY +INPUT_PORTS_END + +static INPUT_PORTS_START( nes_ccpad_left ) + PORT_START("JOYPAD") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN ) PORT_8WAY +INPUT_PORTS_END + +static INPUT_PORTS_START( nes_ccpad_right ) + PORT_START("JOYPAD") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN ) PORT_8WAY +INPUT_PORTS_END + +static INPUT_PORTS_START( nes_arcstick ) + PORT_START("CONFIG") + PORT_CONFNAME( 0x01, 0x01, "4 Way / 8 Way Joystick") + PORT_CONFSETTING( 0x00, "4 Way" ) + PORT_CONFSETTING( 0x01, "8 Way" ) + PORT_CONFNAME( 0x02, 0x00, "Player ID") + PORT_CONFSETTING( 0x00, "Player I" ) + PORT_CONFSETTING( 0x02, "Player II" ) + + PORT_START("JOYPAD") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_joypad_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_joypad ); +} + +ioport_constructor nes_fcpad2_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_fcpad_p2 ); +} + +ioport_constructor nes_ccpadl_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_ccpad_left ); +} + +ioport_constructor nes_ccpadr_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_ccpad_right ); +} + +ioport_constructor nes_arcstick_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_arcstick ); +} + + + +static SLOT_INTERFACE_START( arcstick_daisy ) + SLOT_INTERFACE("arcstick", NES_ARCSTICK) +SLOT_INTERFACE_END + +static MACHINE_CONFIG_FRAGMENT( arcstick ) + // expansion port to allow daisy chaining + MCFG_FC_EXPANSION_PORT_ADD("subexp", arcstick_daisy, NULL) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor nes_arcstick_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( arcstick ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_joypad_device - constructor +//------------------------------------------------- + +nes_joypad_device::nes_joypad_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_nes_control_port_interface(mconfig, *this), + m_joypad(*this, "JOYPAD") +{ +} + +nes_joypad_device::nes_joypad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_JOYPAD, "Nintendo NES / FC Control Pad", tag, owner, clock, "nes_joypad", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_joypad(*this, "JOYPAD") +{ +} + +nes_fcpad2_device::nes_fcpad2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + nes_joypad_device(mconfig, NES_FCPAD_P2, "Nintendo Family Computer P2 Pad", tag, owner, clock, "nes_fcpad2", __FILE__) +{ +} + +nes_ccpadl_device::nes_ccpadl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + nes_joypad_device(mconfig, NES_CCPAD_LEFT, "Crazy Climber Left Pad", tag, owner, clock, "nes_ccpadl", __FILE__) +{ +} + +nes_ccpadr_device::nes_ccpadr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + nes_joypad_device(mconfig, NES_CCPAD_RIGHT, "Crazy Climber Right Pad", tag, owner, clock, "nes_ccpadr", __FILE__) +{ +} + +nes_arcstick_device::nes_arcstick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + nes_joypad_device(mconfig, NES_ARCSTICK, "Nintendo Family Computer Arcade Stick", tag, owner, clock, "nes_arcstick", __FILE__), + m_daisychain(*this, "subexp"), + m_cfg(*this, "CONFIG") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_joypad_device::device_start() +{ + save_item(NAME(m_latch)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_joypad_device::device_reset() +{ + m_latch = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_joypad_device::read_bit0() +{ + UINT8 ret = m_latch & 1; + m_latch >>= 1; + return ret; +} + +UINT8 nes_fcpad2_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (!offset) // microphone input + ret |= m_joypad->read() & 0x04; + + return ret; +} + +// NOTE: I haven't found any documentation about what happens when +// users connect two arcade stick both set as P1 or P2 in config. +// does the FC only acknowledge the first one, or do they conflict +// with each other? currently, we only support the following setup: +// if the first pad is set as P1, the daisy chained pad is checked +// for P2 only, and vice versa. +UINT8 nes_arcstick_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 0) //$4016 + { + if ((m_cfg->read() & 2) == 0) // we are P1 input + { + ret |= (m_latch & 1) << 1; + m_latch >>= 1; + } + else + ret |= m_daisychain->read_exp(0); + } + else //$4017 + { + if ((m_cfg->read() & 2) == 2) // we are P2 input + { + ret |= (m_latch & 1) << 1; + m_latch >>= 1; + } + else + ret |= m_daisychain->read_exp(1); + } + + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_joypad_device::write(UINT8 data) +{ + if (data & 0x01) + return; + + m_latch = m_joypad->read(); +} + +void nes_fcpad2_device::write(UINT8 data) +{ + if (data & 0x01) + return; + + // microphone is hooked to expansion bits, not to the controller bit + m_latch = m_joypad->read() & ~0x04; +} + +void nes_arcstick_device::write(UINT8 data) +{ + m_daisychain->write(data); + + if (data & 0x01) + return; + + m_latch = m_joypad->read(); +} + diff --git a/src/emu/bus/nes_ctrl/joypad.h b/src/emu/bus/nes_ctrl/joypad.h new file mode 100644 index 00000000000..00c6aea58e4 --- /dev/null +++ b/src/emu/bus/nes_ctrl/joypad.h @@ -0,0 +1,112 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System Joypads + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_JOYPAD__ +#define __NES_JOYPAD__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_joypad_device + +class nes_joypad_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_joypad_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + nes_joypad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_bit0(); + virtual void write(UINT8 data); + + required_ioport m_joypad; + UINT32 m_latch; +}; + +// ======================> nes_fcpad2_device + +class nes_fcpad2_device : public nes_joypad_device +{ +public: + // construction/destruction + nes_fcpad2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); +}; + +// ======================> nes_ccpadl_device + +class nes_ccpadl_device : public nes_joypad_device +{ +public: + // construction/destruction + nes_ccpadl_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; +}; + +// ======================> nes_ccpadr_device + +class nes_ccpadr_device : public nes_joypad_device +{ +public: + // construction/destruction + nes_ccpadr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; +}; + +// ======================> nes_arcstick_device + +class nes_arcstick_device : public nes_joypad_device +{ +public: + // construction/destruction + nes_arcstick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + virtual UINT8 read_bit0() { return 0; } + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + + required_device<nes_control_port_device> m_daisychain; + required_ioport m_cfg; +}; + + +// device type definition +extern const device_type NES_JOYPAD; +extern const device_type NES_FCPAD_P2; +extern const device_type NES_CCPAD_LEFT; +extern const device_type NES_CCPAD_RIGHT; +extern const device_type NES_ARCSTICK; + +#endif diff --git a/src/emu/bus/nes_ctrl/konamihs.c b/src/emu/bus/nes_ctrl/konamihs.c new file mode 100644 index 00000000000..187d3d80e2e --- /dev/null +++ b/src/emu/bus/nes_ctrl/konamihs.c @@ -0,0 +1,102 @@ +/********************************************************************** + + Nintendo Family Computer Konami Hyper Shot Controllers + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "konamihs.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_KONAMIHS = &device_creator<nes_konamihs_device>; + + +static INPUT_PORTS_START( nes_konamihs ) + PORT_START("P1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("PI Run") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("PI Jump") + + PORT_START("P2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("PII Run") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("PII Jump") +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_konamihs_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_konamihs ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_konamihs_device - constructor +//------------------------------------------------- + +nes_konamihs_device::nes_konamihs_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_KONAMIHS, "Konami Hyper Shot Controller", tag, owner, clock, "nes_konamihs", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_ipt_p1(*this, "P1"), + m_ipt_p2(*this, "P2") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_konamihs_device::device_start() +{ + save_item(NAME(m_latch_p1)); + save_item(NAME(m_latch_p2)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_konamihs_device::device_reset() +{ + m_latch_p1 = 0; + m_latch_p2 = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_konamihs_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 1) //$4017 + { + ret |= m_latch_p1 << 1; + ret |= m_latch_p2 << 3; + } + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_konamihs_device::write(UINT8 data) +{ + if ((data & 0x02) == 0) + m_latch_p1 = m_ipt_p1->read(); + if ((data & 0x04) == 0) + m_latch_p2 = m_ipt_p2->read(); +} diff --git a/src/emu/bus/nes_ctrl/konamihs.h b/src/emu/bus/nes_ctrl/konamihs.h new file mode 100644 index 00000000000..71d6dd737cb --- /dev/null +++ b/src/emu/bus/nes_ctrl/konamihs.h @@ -0,0 +1,50 @@ +/********************************************************************** + + Nintendo Family Computer Konami Hyper Shot Controllers + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_KONAMIHS__ +#define __NES_KONAMIHS__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_konamihs_device + +class nes_konamihs_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_konamihs_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + + required_ioport m_ipt_p1; + required_ioport m_ipt_p2; + UINT32 m_latch_p1, m_latch_p2; +}; + +// device type definition +extern const device_type NES_KONAMIHS; + +#endif diff --git a/src/emu/bus/nes_ctrl/miracle.c b/src/emu/bus/nes_ctrl/miracle.c new file mode 100644 index 00000000000..82ce2cc3796 --- /dev/null +++ b/src/emu/bus/nes_ctrl/miracle.c @@ -0,0 +1,178 @@ +/********************************************************************** + + Nintendo Entertainment System - Miracle Piano Keyboard + + TODO: basically everything, this is just a skeleton with no + real MIDI handling at the moment. + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "miracle.h" +#include "bus/midi/midi.h" + +#define MIRACLE_MIDI_WAITING 0 +#define MIRACLE_MIDI_RECEIVE 1 +#define MIRACLE_MIDI_SEND 2 + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_MIRACLE = &device_creator<nes_miracle_device>; + + +MACHINE_CONFIG_FRAGMENT( nes_miracle ) +// MCFG_CPU_ADD("piano_cpu", I8051, XTAL_11_0592MHz) // xtal to be verified + + MCFG_MIDI_PORT_ADD("mdin", midiin_slot, "midiin") + MCFG_MIDI_PORT_ADD("mdout", midiout_slot, "midiout") +MACHINE_CONFIG_END + +machine_config_constructor nes_miracle_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( nes_miracle ); +} + + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void nes_miracle_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (id == TIMER_STROBE_ON) + { + m_strobe_clock++; + } +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_miracle_device - constructor +//------------------------------------------------- + +nes_miracle_device::nes_miracle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_MIRACLE, "Miracle Piano Controller", tag, owner, clock, "nes_miracle", __FILE__) + , device_nes_control_port_interface(mconfig, *this) +// , m_cpu(*this, "piano_cpu") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_miracle_device::device_start() +{ + strobe_timer = timer_alloc(TIMER_STROBE_ON); + strobe_timer->adjust(attotime::never); + save_item(NAME(m_strobe_on)); + save_item(NAME(m_sent_bits)); + save_item(NAME(m_strobe_clock)); + save_item(NAME(m_midi_mode)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_miracle_device::device_reset() +{ + m_strobe_on = 0; + m_sent_bits = 0; + m_strobe_clock = 0; + m_midi_mode = MIRACLE_MIDI_WAITING; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +// TODO: here, reads from serial midi in bit0, when in MIDI_SEND mode + +UINT8 nes_miracle_device::read_bit0() +{ + UINT8 ret = 0; + if (m_strobe_clock >= 66) + { + // more than 66 clocks since strobe on write means send mode + m_midi_mode = MIRACLE_MIDI_SEND; + strobe_timer->reset(); + m_strobe_on = 0; + m_strobe_clock = 0; +// printf("send start\n"); + } + + if (m_midi_mode == MIRACLE_MIDI_SEND) + { + //NES reads from Miracle Piano! + // ret |= ... + } + + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +// TODO: here, writes to serial midi in bit0, when in MIDI_RECEIVE mode + +void nes_miracle_device::write(UINT8 data) +{ + if (data == 1 && !m_strobe_on) + { + strobe_timer->adjust(attotime::zero, 0, machine().device<cpu_device>("maincpu")->cycles_to_attotime(1)); + m_strobe_on = 1; + return; + } + + if (m_strobe_on) + { + // was timer running? + if (m_strobe_clock > 0) + { + if (m_strobe_clock < 66 && data == 0) + { + // less than 66 clocks before new write means receive mode + m_midi_mode = MIRACLE_MIDI_RECEIVE; +// printf("receive start\n"); + strobe_timer->reset(); + m_strobe_on = 0; + m_strobe_clock = 0; + return; + } + } + + if (m_midi_mode == MIRACLE_MIDI_SEND && data == 0) + { + // strobe off after the end of a byte + m_midi_mode = MIRACLE_MIDI_WAITING; +// printf("send end\n"); + } + } + + if (m_midi_mode == MIRACLE_MIDI_RECEIVE) + { + //NES writes (data & 1) to Miracle Piano! + // 1st write is data present flag (1=data present) + // next 8 writes are actual data bits (with ^1) + m_sent_bits++; + // then we go back to waiting + if (m_sent_bits == 9) + { +// printf("receive end\n"); + m_midi_mode = MIRACLE_MIDI_WAITING; + m_sent_bits = 0; + } + } +} diff --git a/src/emu/bus/nes_ctrl/miracle.h b/src/emu/bus/nes_ctrl/miracle.h new file mode 100644 index 00000000000..fcc8c17c42b --- /dev/null +++ b/src/emu/bus/nes_ctrl/miracle.h @@ -0,0 +1,55 @@ +/********************************************************************** + + Nintendo Entertainment System - Miracle Piano Keyboard + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_MIRACLE__ +#define __NES_MIRACLE__ + + +#include "emu.h" +#include "ctrl.h" +//#include "cpu/mcs51/mcs51.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_miracle_device + +class nes_miracle_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_miracle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_bit0(); + virtual void write(UINT8 data); + + static const device_timer_id TIMER_STROBE_ON = 0; + emu_timer *strobe_timer; + + //required_device<i8051_device> m_cpu; + int m_strobe_on, m_midi_mode, m_sent_bits; + UINT32 m_strobe_clock; +}; + +// device type definition +extern const device_type NES_MIRACLE; + +#endif diff --git a/src/emu/bus/nes_ctrl/mjpanel.c b/src/emu/bus/nes_ctrl/mjpanel.c new file mode 100644 index 00000000000..16e582338c9 --- /dev/null +++ b/src/emu/bus/nes_ctrl/mjpanel.c @@ -0,0 +1,132 @@ +/********************************************************************** + + Nintendo Family Computer Mahjong Panel + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "mjpanel.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_MJPANEL = &device_creator<nes_mjpanel_device>; + + +static INPUT_PORTS_START( nes_mjpanel ) + PORT_START("MJPANEL.0") + PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("MJPANEL.1") + PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_N ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_M ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_L ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_K ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_J ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_I ) + + PORT_START("MJPANEL.2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_MAHJONG_H ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_G ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_F ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_E ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_D ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_C ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_B ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_A ) + + PORT_START("MJPANEL.3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_RON ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_REACH ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_CHI ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_PON ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_KAN ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Mahjong Select") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("Mahjong Start") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_mjpanel_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_mjpanel ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_mjpanel_device - constructor +//------------------------------------------------- + +nes_mjpanel_device::nes_mjpanel_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_MJPANEL, "Famicom Mahjong Panel", tag, owner, clock, "nes_mjpanel", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_panel(*this, "MJPANEL") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_mjpanel_device::device_start() +{ + save_item(NAME(m_latch)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_mjpanel_device::device_reset() +{ + m_latch = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_mjpanel_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset) + { + ret = (m_latch & 1) << 1; + m_latch >>= 1; + } + else + logerror("Error: Mahjong panel read from $4016\n"); + + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_mjpanel_device::write(UINT8 data) +{ + if (data & 0x01) + return; + + if (data & 0xf8) + logerror("Error: Mahjong panel read with mux data %02x\n", (data & 0xfe)); + else + m_latch = m_panel[(data & 0xfe) >> 1]->read(); +} diff --git a/src/emu/bus/nes_ctrl/mjpanel.h b/src/emu/bus/nes_ctrl/mjpanel.h new file mode 100644 index 00000000000..6df7680eb26 --- /dev/null +++ b/src/emu/bus/nes_ctrl/mjpanel.h @@ -0,0 +1,52 @@ +/********************************************************************** + + Nintendo Family Computer Mahjong Panel + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_MJPANEL__ +#define __NES_MJPANEL__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_mjpanel_device + +class nes_mjpanel_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_mjpanel_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + +private: + required_ioport_array<4> m_panel; + UINT32 m_latch; +}; + + +// device type definition +extern const device_type NES_MJPANEL; + + +#endif diff --git a/src/emu/bus/nes_ctrl/pachinko.c b/src/emu/bus/nes_ctrl/pachinko.c new file mode 100644 index 00000000000..875aa92e771 --- /dev/null +++ b/src/emu/bus/nes_ctrl/pachinko.c @@ -0,0 +1,108 @@ +/********************************************************************** + + Nintendo Family Computer Pachinko Controller + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "pachinko.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_PACHINKO = &device_creator<nes_pachinko_device>; + + +static INPUT_PORTS_START( nes_pachinko ) + PORT_START("JOYPAD") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY + + PORT_START("TRIGGER") + PORT_BIT( 0xff, 0, IPT_PEDAL ) PORT_MINMAX(0, 0x63) PORT_SENSITIVITY(25) PORT_KEYDELTA(20) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_pachinko_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_pachinko ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_pachinko_device - constructor +//------------------------------------------------- + +nes_pachinko_device::nes_pachinko_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_PACHINKO, "Famicom Pachinko Controller", tag, owner, clock, "nes_pachinko", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_joypad(*this, "JOYPAD"), + m_trigger(*this, "TRIGGER") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_pachinko_device::device_start() +{ + save_item(NAME(m_latch)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_pachinko_device::device_reset() +{ + m_latch = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_pachinko_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + // this controller behaves like a standard P3 joypad, with longer stream of inputs + if (offset == 0) //$4016 + { + ret |= (m_latch & 1) << 1; + m_latch >>= 1; + } + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_pachinko_device::write(UINT8 data) +{ + if (data & 0x01) + return; + + m_latch = m_joypad->read(); + m_latch |= ((m_trigger->read() ^ 0xff) & 0xff) << 8; + m_latch |= 0xff0000; +} diff --git a/src/emu/bus/nes_ctrl/pachinko.h b/src/emu/bus/nes_ctrl/pachinko.h new file mode 100644 index 00000000000..ab07e4fa961 --- /dev/null +++ b/src/emu/bus/nes_ctrl/pachinko.h @@ -0,0 +1,50 @@ +/********************************************************************** + + Nintendo Family Computer Pachinko Controller + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_PACHINKO__ +#define __NES_PACHINKO__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_pachinko_device + +class nes_pachinko_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_pachinko_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + + required_ioport m_joypad; + required_ioport m_trigger; + UINT32 m_latch; +}; + +// device type definition +extern const device_type NES_PACHINKO; + +#endif diff --git a/src/emu/bus/nes_ctrl/partytap.c b/src/emu/bus/nes_ctrl/partytap.c new file mode 100644 index 00000000000..f81fb89bd2f --- /dev/null +++ b/src/emu/bus/nes_ctrl/partytap.c @@ -0,0 +1,108 @@ +/********************************************************************** + + Nintendo Family Computer Yonezawa / PartyRoom 21 Party Tap Controller + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "partytap.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_PARTYTAP = &device_creator<nes_partytap_device>; + + +static INPUT_PORTS_START( nes_partytap ) + PORT_START("INPUTS") + PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 Button") PORT_CODE(KEYCODE_Z) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 Button") PORT_CODE(KEYCODE_X) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P3 Button") PORT_CODE(KEYCODE_C) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P4 Button") PORT_CODE(KEYCODE_V) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P5 Button") PORT_CODE(KEYCODE_B) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P6 Button") PORT_CODE(KEYCODE_N) +INPUT_PORTS_END + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_partytap_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_partytap ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_partytap_device - constructor +//------------------------------------------------- + +nes_partytap_device::nes_partytap_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_PARTYTAP, "Yonezawa Party Tap Controller", tag, owner, clock, "nes_partytap", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_inputs(*this, "INPUTS") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_partytap_device::device_start() +{ + save_item(NAME(m_latch)); + save_item(NAME(m_mode)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_partytap_device::device_reset() +{ + m_mode = 0xe0; + m_latch = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_partytap_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 1) //$4017 + { + ret |= m_latch & 0x1c; + m_latch >>= 3; + // append mode bits + m_latch |= m_mode; + } + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_partytap_device::write(UINT8 data) +{ + // inputs are read in two chunks of 3 bits, before the second one is read bit2 is written here + // probably a mechanism for the game to detect which group of inputs is being read + m_mode = BIT(data, 2) ? 0xa0 : 0xe0; + + if (data & 0x01) + return; + + m_latch = m_inputs->read(); +} diff --git a/src/emu/bus/nes_ctrl/partytap.h b/src/emu/bus/nes_ctrl/partytap.h new file mode 100644 index 00000000000..1b85832ea4d --- /dev/null +++ b/src/emu/bus/nes_ctrl/partytap.h @@ -0,0 +1,50 @@ +/********************************************************************** + + Nintendo Family Computer Yonezawa / PartyRoom 21 Party Tap Controller + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_PARTYTAP__ +#define __NES_PARTYTAP__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_partytap_device + +class nes_partytap_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_partytap_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + + required_ioport m_inputs; + UINT8 m_mode; + UINT32 m_latch; +}; + +// device type definition +extern const device_type NES_PARTYTAP; + +#endif diff --git a/src/emu/bus/nes_ctrl/powerpad.c b/src/emu/bus/nes_ctrl/powerpad.c new file mode 100644 index 00000000000..ba3a5795b43 --- /dev/null +++ b/src/emu/bus/nes_ctrl/powerpad.c @@ -0,0 +1,136 @@ +/********************************************************************** + + Nintendo Entertainment System - Bandai Power Pad + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "powerpad.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_POWERPAD = &device_creator<nes_powerpad_device>; + + +static INPUT_PORTS_START( nes_powerpad ) + PORT_START("LAYOUT") + PORT_CONFNAME( 0x01, 0x00, "Power Pad Button Layout") + PORT_CONFSETTING( 0x00, "Side A" ) + PORT_CONFSETTING( 0x01, "Side B" ) + + // difference between the two sides is that we mirror the key mapping to match the real pad layout! + PORT_START("POWERPAD1") + // side A layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Top1") PORT_CODE(KEYCODE_Y) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid1") PORT_CODE(KEYCODE_J) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid2") PORT_CODE(KEYCODE_H) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Low1") PORT_CODE(KEYCODE_N) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Low2") PORT_CODE(KEYCODE_B) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid3") PORT_CODE(KEYCODE_G) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + // side B layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 2") PORT_CODE(KEYCODE_T) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 1") PORT_CODE(KEYCODE_R) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 5") PORT_CODE(KEYCODE_F) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 9") PORT_CODE(KEYCODE_V) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 6") PORT_CODE(KEYCODE_G) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 10") PORT_CODE(KEYCODE_B) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 11") PORT_CODE(KEYCODE_N) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 7") PORT_CODE(KEYCODE_H) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + + PORT_START("POWERPAD2") + // side A layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Top2") PORT_CODE(KEYCODE_T) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid4") PORT_CODE(KEYCODE_F) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x00) + // side B layout + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 4") PORT_CODE(KEYCODE_U) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 3") PORT_CODE(KEYCODE_Y) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 12") PORT_CODE(KEYCODE_M) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 8") PORT_CODE(KEYCODE_J) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("LAYOUT", 0x01, EQUALS, 0x01) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_powerpad_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_powerpad ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_powerpad_device - constructor +//------------------------------------------------- + +nes_powerpad_device::nes_powerpad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_POWERPAD, "Bandai Power Pad", tag, owner, clock, "nes_powerpad", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_ipt1(*this, "POWERPAD1"), + m_ipt2(*this, "POWERPAD2") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_powerpad_device::device_start() +{ + save_item(NAME(m_latch)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_powerpad_device::device_reset() +{ + m_latch[0] = 0; + m_latch[1] = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_powerpad_device::read_bit34() +{ + UINT8 ret = 0; + ret |= (m_latch[0] & 0x01) << 3; + ret |= (m_latch[1] & 0x01) << 4; + m_latch[0] >>= 1; + m_latch[1] >>= 1; + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_powerpad_device::write(UINT8 data) +{ + if (data & 0x01) + return; + + m_latch[0] = m_ipt1->read(); + m_latch[1] = m_ipt2->read() | 0xf0; +} diff --git a/src/emu/bus/nes_ctrl/powerpad.h b/src/emu/bus/nes_ctrl/powerpad.h new file mode 100644 index 00000000000..0bf6d5fa53d --- /dev/null +++ b/src/emu/bus/nes_ctrl/powerpad.h @@ -0,0 +1,53 @@ +/********************************************************************** + + Nintendo Entertainment System - Bandai Power Pad + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_POWERPAD__ +#define __NES_POWERPAD__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_powerpad_device + +class nes_powerpad_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_powerpad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_bit34(); + virtual void write(UINT8 data); + +private: + required_ioport m_ipt1; + required_ioport m_ipt2; + UINT32 m_latch[2]; +}; + + +// device type definition +extern const device_type NES_POWERPAD; + + +#endif diff --git a/src/emu/bus/nes_ctrl/suborkey.c b/src/emu/bus/nes_ctrl/suborkey.c new file mode 100644 index 00000000000..eb937120d1c --- /dev/null +++ b/src/emu/bus/nes_ctrl/suborkey.c @@ -0,0 +1,230 @@ +/********************************************************************** + + Nintendo Family Computer Subor Keyboard (used by some Famiclones) + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "suborkey.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_SUBORKEYBOARD = &device_creator<nes_suborkey_device>; + + +static INPUT_PORTS_START( fc_suborkey ) + PORT_START("SUBOR.0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + + PORT_START("SUBOR.1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + + PORT_START("SUBOR.2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NEXT") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PRIOR") + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) + + PORT_START("SUBOR.3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') + + PORT_START("SUBOR.4") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + + PORT_START("SUBOR.5") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + + PORT_START("SUBOR.6") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + + PORT_START("SUBOR.7") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + + PORT_START("SUBOR.8") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + + PORT_START("SUBOR.9") + PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("SUBOR.10") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LMENU") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + + PORT_START("SUBOR.11") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD)PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD)PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) + + PORT_START("SUBOR.12") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PAUSE") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE2") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_suborkey_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( fc_suborkey ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_suborkey_device - constructor +//------------------------------------------------- + +nes_suborkey_device::nes_suborkey_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_SUBORKEYBOARD, "FC Subor Keyboard", tag, owner, clock, "nes_suborkey", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_kbd(*this, "SUBOR") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_suborkey_device::device_start() +{ + save_item(NAME(m_fck_scan)); + save_item(NAME(m_fck_mode)); +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_suborkey_device::device_reset() +{ + m_fck_scan = 0; + m_fck_mode = 0; +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_suborkey_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 1) //$4017 + { + // Subor Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 + if (m_fck_scan < 13) + ret |= ~(((m_kbd[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; + else + ret |= 0x1e; + } + + return ret; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +void nes_suborkey_device::write(UINT8 data) +{ + if (BIT(data, 2)) // keyboard active + { + UINT8 out = BIT(data, 1); // scan + if (m_fck_mode && !out && ++m_fck_scan > 12) + m_fck_scan = 0; + + m_fck_mode = out; // access lower or upper 4 bits + + if (BIT(data, 0)) // reset + m_fck_scan = 0; + } +} diff --git a/src/emu/bus/nes_ctrl/suborkey.h b/src/emu/bus/nes_ctrl/suborkey.h new file mode 100644 index 00000000000..c48c9715657 --- /dev/null +++ b/src/emu/bus/nes_ctrl/suborkey.h @@ -0,0 +1,52 @@ +/********************************************************************** + + Nintendo Family Computer Subor Keyboard (used by some Famiclones) + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_SUBORKEY__ +#define __NES_SUBORKEY__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_suborkey_device + +class nes_suborkey_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_suborkey_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_exp(offs_t offset); + virtual void write(UINT8 data); + +private: + required_ioport_array<13> m_kbd; + UINT8 m_fck_scan, m_fck_mode; +}; + + +// device type definition +extern const device_type NES_SUBORKEYBOARD; + + +#endif diff --git a/src/emu/bus/nes_ctrl/zapper.c b/src/emu/bus/nes_ctrl/zapper.c new file mode 100644 index 00000000000..36965206f46 --- /dev/null +++ b/src/emu/bus/nes_ctrl/zapper.c @@ -0,0 +1,97 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System Zapper Lightgun + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "zapper.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_ZAPPER = &device_creator<nes_zapper_device>; + + +static INPUT_PORTS_START( nes_zapper ) + PORT_START("ZAPPER_X") + PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(70) PORT_KEYDELTA(30) PORT_MINMAX(0,255) + PORT_START("ZAPPER_Y") + PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255) + PORT_START("ZAPPER_T") + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Lightgun Trigger") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor nes_zapper_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_zapper ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_zapper_device - constructor +//------------------------------------------------- + +nes_zapper_device::nes_zapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, NES_ZAPPER, "Nintendo Zapper Lightgun", tag, owner, clock, "nes_zapper", __FILE__), + device_nes_control_port_interface(mconfig, *this), + m_lightx(*this, "ZAPPER_X"), + m_lighty(*this, "ZAPPER_Y"), + m_trigger(*this, "ZAPPER_T") +{ +} + + +//------------------------------------------------- +// device_start +//------------------------------------------------- + +void nes_zapper_device::device_start() +{ +} + + +//------------------------------------------------- +// device_reset +//------------------------------------------------- + +void nes_zapper_device::device_reset() +{ +} + + +//------------------------------------------------- +// read +//------------------------------------------------- + +UINT8 nes_zapper_device::read_bit34() +{ + UINT8 ret = m_trigger->read(); + if (!m_port->m_brightpixel_cb.isnull() && + m_port->m_brightpixel_cb(m_lightx->read(), m_lighty->read())) + ret &= ~0x08; // sprite hit + else + ret |= 0x08; // no sprite hit + return ret; +} + +UINT8 nes_zapper_device::read_exp(offs_t offset) +{ + UINT8 ret = 0; + if (offset == 1) // $4017 + ret |= nes_zapper_device::read_bit34(); + return ret; +} diff --git a/src/emu/bus/nes_ctrl/zapper.h b/src/emu/bus/nes_ctrl/zapper.h new file mode 100644 index 00000000000..ed19fdfc265 --- /dev/null +++ b/src/emu/bus/nes_ctrl/zapper.h @@ -0,0 +1,53 @@ +/********************************************************************** + + Nintendo Family Computer & Entertainment System Zapper Lightgun + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __NES_ZAPPER__ +#define __NES_ZAPPER__ + + +#include "emu.h" +#include "ctrl.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_zapper_device + +class nes_zapper_device : public device_t, + public device_nes_control_port_interface +{ +public: + // construction/destruction + nes_zapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + virtual UINT8 read_bit34(); + virtual UINT8 read_exp(offs_t offset); + +private: + required_ioport m_lightx; + required_ioport m_lighty; + required_ioport m_trigger; +}; + + +// device type definition +extern const device_type NES_ZAPPER; + + +#endif diff --git a/src/mess/drivers/nes.c b/src/mess/drivers/nes.c index 11b47141047..9a5ff708c76 100644 --- a/src/mess/drivers/nes.c +++ b/src/mess/drivers/nes.c @@ -48,140 +48,8 @@ static ADDRESS_MAP_START( nes_map, AS_PROGRAM, 8, nes_state ) // 0x8000-0xffff -> HIGH HANDLER defined on a pcb base ADDRESS_MAP_END - -static INPUT_PORTS_START( nes_pads12 ) - PORT_START("PAD1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - - PORT_START("PAD2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - 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) -INPUT_PORTS_END - -static INPUT_PORTS_START( nes_pads34 ) - PORT_START("PAD3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3 A") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3 B") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - - PORT_START("PAD4") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4 A") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4 B") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) -INPUT_PORTS_END - - -static INPUT_PORTS_START( nes_powerpad ) -// difference between the two sides is that we mirror the key mapping to match the real pad layout! - PORT_START("POWERPAD1") -// side A layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Top1") PORT_CODE(KEYCODE_Y) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid1") PORT_CODE(KEYCODE_J) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid2") PORT_CODE(KEYCODE_H) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Low1") PORT_CODE(KEYCODE_N) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Low2") PORT_CODE(KEYCODE_B) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid3") PORT_CODE(KEYCODE_G) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) -// side B layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 2") PORT_CODE(KEYCODE_T) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 1") PORT_CODE(KEYCODE_R) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 5") PORT_CODE(KEYCODE_F) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 9") PORT_CODE(KEYCODE_V) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 6") PORT_CODE(KEYCODE_G) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 10") PORT_CODE(KEYCODE_B) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 11") PORT_CODE(KEYCODE_N) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 7") PORT_CODE(KEYCODE_H) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_START("POWERPAD2") -// side A layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Top2") PORT_CODE(KEYCODE_T) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad Mid4") PORT_CODE(KEYCODE_F) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) - PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0050) -// side B layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 4") PORT_CODE(KEYCODE_U) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 3") PORT_CODE(KEYCODE_Y) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 12") PORT_CODE(KEYCODE_M) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("PowerPad 8") PORT_CODE(KEYCODE_J) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) - PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0060) -INPUT_PORTS_END - -static INPUT_PORTS_START( nes_zapper1 ) - PORT_START("ZAPPER1_X") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(70) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_START("ZAPPER1_Y") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_START("ZAPPER1_T") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P1 Lightgun Trigger") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) -INPUT_PORTS_END - -static INPUT_PORTS_START( nes_zapper2 ) - PORT_START("ZAPPER2_X") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(70) PORT_KEYDELTA(30) PORT_MINMAX(0,255 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_START("ZAPPER2_Y") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_START("ZAPPER2_T") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("P2 Lightgun Trigger") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) -INPUT_PORTS_END - -static INPUT_PORTS_START( nes_paddle ) - PORT_START("PADDLE") - PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) PORT_CENTERDELTA(0) PORT_MINMAX(0x62,0xf2) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0040) - PORT_START("PADDLE_BUTTON") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Paddle button") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0040) -INPUT_PORTS_END - static INPUT_PORTS_START( nes ) - PORT_INCLUDE( nes_pads12 ) - PORT_INCLUDE( nes_pads34 ) - PORT_INCLUDE( nes_powerpad ) - PORT_INCLUDE( nes_zapper1 ) - PORT_INCLUDE( nes_zapper2 ) - PORT_INCLUDE( nes_paddle ) - - PORT_START("CTRLSEL") - PORT_CONFNAME( 0x000f, 0x0001, "P1 Controller") - PORT_CONFSETTING( 0x0000, "Unconnected" ) - PORT_CONFSETTING( 0x0001, "Gamepad" ) - PORT_CONFSETTING( 0x0002, "Zapper" ) - PORT_CONFNAME( 0x00f0, 0x0010, "P2 Controller") - PORT_CONFSETTING( 0x0000, "Unconnected" ) - PORT_CONFSETTING( 0x0010, "Gamepad" ) - PORT_CONFSETTING( 0x0020, "Zapper" ) - PORT_CONFSETTING( 0x0040, "Arkanoid paddle" ) - PORT_CONFSETTING( 0x0050, "Power Pad (Side A layout)" ) - PORT_CONFSETTING( 0x0060, "Power Pad (Side B layout)" ) - PORT_CONFNAME( 0x0f00, 0x0000, "P3 Controller") - PORT_CONFSETTING( 0x0000, "Unconnected" ) - PORT_CONFSETTING( 0x0100, "Gamepad" ) - PORT_CONFNAME( 0xf000, 0x0000, "P4 Controller") - PORT_CONFSETTING( 0x0000, "Unconnected" ) - PORT_CONFSETTING( 0x1000, "Gamepad" ) - + // input devices go through slot options PORT_START("CONFIG") PORT_CONFNAME( 0x01, 0x00, "Draw Top/Bottom 8 Lines") PORT_CONFSETTING( 0x01, DEF_STR(No) ) @@ -191,440 +59,8 @@ static INPUT_PORTS_START( nes ) PORT_CONFSETTING( 0x00, DEF_STR(Yes) ) INPUT_PORTS_END - -static INPUT_PORTS_START( fc_pads12 ) - PORT_START("PAD1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0001) - - PORT_START("PAD2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0010) - 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 - -static INPUT_PORTS_START( fc_pads34 ) - PORT_START("PAD3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P3 A") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P3 B") PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) PORT_CONDITION("CTRLSEL", 0x0f00, EQUALS, 0x0100) - - PORT_START("PAD4") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P4 A") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P4 B") PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4) PORT_CONDITION("CTRLSEL", 0xf000, EQUALS, 0x1000) -INPUT_PORTS_END - -static INPUT_PORTS_START( fc_lightgun ) - PORT_START("ZAPPER2_X") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(70) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x01) - PORT_START("ZAPPER2_Y") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(30) PORT_MINMAX(0,255) PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x01) - PORT_START("ZAPPER2_T") - PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Lightgun Trigger") PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x01) -INPUT_PORTS_END - -static INPUT_PORTS_START( fc_paddle ) - PORT_START("PADDLE") - PORT_BIT( 0xff, 0x7f, IPT_PADDLE) PORT_SENSITIVITY(25) PORT_KEYDELTA(25) PORT_CENTERDELTA(0) PORT_MINMAX(0x62,0xf2) PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x04) - PORT_START("PADDLE_BUTTON") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Paddle button") PORT_PLAYER(2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x04) -INPUT_PORTS_END - -static INPUT_PORTS_START( fc_cclimb ) - PORT_START("CC_LEFT") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x000f, EQUALS, 0x0002) - - PORT_START("CC_RIGHT") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_PLAYER(1)PORT_CONDITION("CTRLSEL", 0x00f0, EQUALS, 0x0020) -INPUT_PORTS_END - -static INPUT_PORTS_START( fc_keyboard ) - PORT_START("FCKEY0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Kana") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RSHIFT) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('\\') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Stop") PORT_CODE(KEYCODE_BACKSPACE) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('_') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CHAR('/') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY4") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY5") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY6") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY7") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Grph") PORT_CODE(KEYCODE_LALT) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - - PORT_START("FCKEY8") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Clr") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Del") PORT_CODE(KEYCODE_DEL) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ins") PORT_CODE(KEYCODE_INSERT) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x02) - -INPUT_PORTS_END - -static INPUT_PORTS_START( subor_keyboard ) - PORT_START("SUBKEY0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("NEXT") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8) PORT_CHAR(UCHAR_MAMEKEY(F8)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PRIOR") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL) PORT_CHAR(UCHAR_MAMEKEY(DEL)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F5)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY4") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F7)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY5") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY6") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY7") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F6)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY8") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY9") - PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY10") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LMENU") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F11) PORT_CHAR(UCHAR_MAMEKEY(F11)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12) PORT_CHAR(UCHAR_MAMEKEY(F12)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY11") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS_PAD)PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10) PORT_CHAR(UCHAR_MAMEKEY(F10)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH_PAD)PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) PORT_CHAR(UCHAR_MAMEKEY(NUMLOCK)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - - PORT_START("SUBKEY12") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("PAUSE") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("SPACE2") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9) PORT_CHAR(UCHAR_MAMEKEY(F9)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x03) - -INPUT_PORTS_END - -static INPUT_PORTS_START( mahjong_panel ) - PORT_START("MAH0") - PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - - PORT_START("MAH1") - PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_N ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_M ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_L ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_K ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_J ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_I ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - - PORT_START("MAH2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_MAHJONG_H ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_G ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_F ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_E ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_D ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_C ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_MAHJONG_B ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_MAHJONG_A ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - - PORT_START("MAH3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_MAHJONG_RON ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_MAHJONG_REACH ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MAHJONG_CHI ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MAHJONG_PON ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_MAHJONG_KAN ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("P1 Mahjong Select") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Mahjong Start") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x07) -INPUT_PORTS_END - -// these are read differently than the powerpad inputs, but we share the tags, to reduce -static INPUT_PORTS_START( fc_ftrainer ) -// difference between the two sides is that we mirror the key mapping to match the real pad layout! - PORT_START("FT_COL0") -// side A layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid1") PORT_CODE(KEYCODE_J) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) -// side B layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 12") PORT_CODE(KEYCODE_M) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 8") PORT_CODE(KEYCODE_J) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 4") PORT_CODE(KEYCODE_U) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - - PORT_START("FT_COL1") -// side A layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Low1") PORT_CODE(KEYCODE_N) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid2") PORT_CODE(KEYCODE_H) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Top1") PORT_CODE(KEYCODE_Y) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) -// side B layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 11") PORT_CODE(KEYCODE_N) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 7") PORT_CODE(KEYCODE_H) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 3") PORT_CODE(KEYCODE_Y) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - - PORT_START("FT_COL2") -// side A layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Low2") PORT_CODE(KEYCODE_B) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid3") PORT_CODE(KEYCODE_G) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Top2") PORT_CODE(KEYCODE_T) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) -// side B layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 10") PORT_CODE(KEYCODE_B) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 6") PORT_CODE(KEYCODE_G) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 2") PORT_CODE(KEYCODE_T) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - - PORT_START("FT_COL3") -// side A layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer Mid4") PORT_CODE(KEYCODE_F) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x05) -// side B layout - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 9") PORT_CODE(KEYCODE_V) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 5") PORT_CODE(KEYCODE_F) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("Family Trainer 1") PORT_CODE(KEYCODE_R) PORT_CONDITION("EXP", 0x0f, EQUALS, 0x06) -INPUT_PORTS_END - - - static INPUT_PORTS_START( famicom ) - PORT_INCLUDE( fc_pads12 ) - PORT_INCLUDE( fc_pads34 ) - PORT_INCLUDE( fc_lightgun ) - // FIXME: was it possible to attache two paddles in a Famicom (as the Arkanoid 2 box suggests)?!? investigate... - PORT_INCLUDE( fc_paddle ) - // Crazy Climber is not really a separate controller, but a couple of small sticks to be - // put on top of d-pads of the regular controllers. Users should then control the game - // by using both controllers, turned 90 degrees, as a couple of dual sticks as in the arcade - PORT_INCLUDE( fc_cclimb ) - PORT_INCLUDE( fc_keyboard ) - PORT_INCLUDE( subor_keyboard ) - PORT_INCLUDE( mahjong_panel ) - PORT_INCLUDE( fc_ftrainer ) - - PORT_START("CTRLSEL") - PORT_CONFNAME( 0x000f, 0x0001, "P1 Controller") - PORT_CONFSETTING( 0x0000, "Unconnected" ) - PORT_CONFSETTING( 0x0001, "Gamepad" ) - PORT_CONFSETTING( 0x0002, "Crazy Climber pad (Left)" ) - PORT_CONFNAME( 0x00f0, 0x0010, "P2 Controller") - 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, 0x08) - PORT_CONFSETTING( 0x0000, "Unconnected" ) - PORT_CONFSETTING( 0x0100, "Gamepad" ) - PORT_CONFNAME( 0xf000, 0x0000, "P4 Controller") PORT_CONDITION("EXP", 0x0f, EQUALS, 0x08) - PORT_CONFSETTING( 0x0000, "Unconnected" ) - PORT_CONFSETTING( 0x1000, "Gamepad" ) - - PORT_START("EXP") - PORT_CONFNAME( 0x0f, 0x00, "Expansion Port") - PORT_CONFSETTING( 0x00, "(Empty)" ) - PORT_CONFSETTING( 0x01, "Light Gun" ) - PORT_CONFSETTING( 0x02, "FC Keyboard" ) - PORT_CONFSETTING( 0x03, "Subor Keyboard" ) - PORT_CONFSETTING( 0x04, "Arkanoid paddle" ) - PORT_CONFSETTING( 0x05, "Family Trainer (Side A)" ) - PORT_CONFSETTING( 0x06, "Family Trainer (Side B)" ) - PORT_CONFSETTING( 0x07, "Mahjong Panel" ) - PORT_CONFSETTING( 0x08, "Hori Twin Adapter" ) - + // input devices go through slot options PORT_START("CONFIG") PORT_CONFNAME( 0x01, 0x00, "Draw Top/Bottom 8 Lines") PORT_CONFSETTING( 0x01, DEF_STR(No) ) @@ -634,7 +70,7 @@ static INPUT_PORTS_START( famicom ) PORT_CONFSETTING( 0x00, DEF_STR(Yes) ) PORT_START("FLIPDISK") /* fake key */ - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Change Disk Side") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Change Disk Side") PORT_CODE(KEYCODE_SPACE) INPUT_PORTS_END @@ -674,6 +110,11 @@ static MACHINE_CONFIG_START( nes, nes_state ) MCFG_NES_APU_CPU("maincpu") MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90) + MCFG_NES_CONTROL_PORT_ADD("ctrl1", nes_control_port1_devices, "joypad") + MCFG_NESCTRL_BRIGHTPIXEL_CB(nes_state, bright_pixel) + MCFG_NES_CONTROL_PORT_ADD("ctrl2", nes_control_port2_devices, "joypad") + MCFG_NESCTRL_BRIGHTPIXEL_CB(nes_state, bright_pixel) + MCFG_NES_CARTRIDGE_ADD("nes_slot", nes_cart, NULL) MCFG_SOFTWARE_LIST_ADD("cart_list", "nes") MCFG_SOFTWARE_LIST_ADD("ade_list", "nes_ade") // Camerica/Codemasters Aladdin Deck Enhancer mini-carts @@ -729,9 +170,12 @@ static MACHINE_CONFIG_DERIVED( dendy, nes ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( famicom, nes ) - MCFG_CASSETTE_ADD( "tape" ) - MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) - MCFG_CASSETTE_INTERFACE("fc_cass") + MCFG_DEVICE_REMOVE("ctrl1") + MCFG_DEVICE_REMOVE("ctrl2") + MCFG_NES_CONTROL_PORT_ADD("ctrl1", fc_control_port1_devices, "joypad") + MCFG_NES_CONTROL_PORT_ADD("ctrl2", fc_control_port2_devices, "joypad") + MCFG_FC_EXPANSION_PORT_ADD("exp", fc_expansion_devices, NULL) + MCFG_NESCTRL_BRIGHTPIXEL_CB(nes_state, bright_pixel) MCFG_SOFTWARE_LIST_ADD("flop_list", "famicom_flop") MCFG_SOFTWARE_LIST_ADD("cass_list", "famicom_cass") @@ -769,9 +213,11 @@ void nes_state::setup_disk(nes_disksys_device *slot) MACHINE_START_MEMBER( nes_state, fds ) { m_ciram = auto_alloc_array(machine(), UINT8, 0x800); - setup_ioports(); setup_disk(m_disk); - state_register(); + + // register saves + save_item(NAME(m_last_frame_flip)); + save_pointer(NAME(m_ciram), 0x800); } MACHINE_RESET_MEMBER( nes_state, fds ) @@ -781,17 +227,11 @@ MACHINE_RESET_MEMBER( nes_state, fds ) // the rest is the same as for nes/famicom/dendy m_maincpu->reset(); - - memset(m_pad_latch, 0, sizeof(m_pad_latch)); - memset(m_zapper_latch, 0, sizeof(m_zapper_latch)); - m_paddle_latch = 0; - m_paddle_btn_latch = 0; } static MACHINE_CONFIG_DERIVED( fds, famicom ) MCFG_MACHINE_START_OVERRIDE( nes_state, fds ) MCFG_MACHINE_RESET_OVERRIDE( nes_state, fds ) - MCFG_DEVICE_REMOVE("tape") MCFG_DEVICE_REMOVE("nes_slot") MCFG_DEVICE_ADD("disk", NES_DISKSYS, 0) @@ -827,11 +267,6 @@ MACHINE_RESET_MEMBER( nes_state, famitwin ) // the rest is the same as for nes/famicom/dendy m_maincpu->reset(); - - memset(m_pad_latch, 0, sizeof(m_pad_latch)); - memset(m_zapper_latch, 0, sizeof(m_zapper_latch)); - m_paddle_latch = 0; - m_paddle_btn_latch = 0; } static MACHINE_CONFIG_DERIVED( famitwin, famicom ) diff --git a/src/mess/includes/nes.h b/src/mess/includes/nes.h index 02b22a2b9c5..7c34c693545 100644 --- a/src/mess/includes/nes.h +++ b/src/mess/includes/nes.h @@ -13,8 +13,8 @@ #include "video/ppu2c0x.h" #include "bus/nes/nes_slot.h" #include "bus/nes/nes_carts.h" +#include "bus/nes_ctrl/ctrl.h" #include "sound/nes_apu.h" -#include "imagedev/cassette.h" /*************************************************************************** CONSTANTS @@ -30,12 +30,6 @@ TYPE DEFINITIONS ***************************************************************************/ -struct nes_input -{ - UINT32 shift; - UINT32 i0, i1, i2; -}; - /*PPU fast banking constants and structures */ #define CHRROM 0 @@ -57,44 +51,22 @@ struct nes_input class nes_state : public driver_device { public: - enum - { - TIMER_ZAPPER_TICK, - TIMER_LIGHTGUN_TICK - }; - nes_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_ppu(*this, "ppu"), m_sound(*this, "nessound"), + m_ctrl1(*this, "ctrl1"), + m_ctrl2(*this, "ctrl2"), + m_exp(*this, "exp"), m_cartslot(*this, "nes_slot"), - m_disk(*this, "disk"), - m_cassette(*this, "tape") + m_disk(*this, "disk") { } /* video-related */ int m_last_frame_flip; /* misc */ - ioport_port *m_io_ctrlsel; - ioport_port *m_io_fckey[9]; - ioport_port *m_io_subkey[13]; - ioport_port *m_io_pad[4]; - ioport_port *m_io_powerpad[2]; - ioport_port *m_io_mahjong[4]; - ioport_port *m_io_ftrainer[4]; - ioport_port *m_io_cc_left; - ioport_port *m_io_cc_right; - ioport_port *m_io_zapper1_t; - ioport_port *m_io_zapper1_x; - ioport_port *m_io_zapper1_y; - ioport_port *m_io_zapper2_t; - ioport_port *m_io_zapper2_x; - ioport_port *m_io_zapper2_y; - ioport_port *m_io_paddle; - ioport_port *m_io_paddle_btn; - ioport_port *m_io_exp; ioport_port *m_io_disksel; UINT8 *m_vram; @@ -103,9 +75,11 @@ public: required_device<cpu_device> m_maincpu; required_device<ppu2c0x_device> m_ppu; required_device<nesapu_device> m_sound; + required_device<nes_control_port_device> m_ctrl1; + required_device<nes_control_port_device> m_ctrl2; + optional_device<nes_control_port_device> m_exp; optional_device<nes_cart_slot_device> m_cartslot; optional_device<nes_disksys_device> m_disk; - optional_device<cassette_image_device> m_cassette; int nes_ppu_vidaccess(int address, int data); void ppu_nmi(int *ppu_regs); @@ -113,7 +87,6 @@ public: DECLARE_READ8_MEMBER(nes_in0_r); DECLARE_READ8_MEMBER(nes_in1_r); DECLARE_WRITE8_MEMBER(nes_in0_w); - DECLARE_WRITE8_MEMBER(nes_in1_w); DECLARE_READ8_MEMBER(fc_in0_r); DECLARE_READ8_MEMBER(fc_in1_r); DECLARE_WRITE8_MEMBER(fc_in0_w); @@ -127,8 +100,7 @@ public: DECLARE_READ8_MEMBER(psg_4015_r); DECLARE_WRITE8_MEMBER(psg_4015_w); DECLARE_WRITE8_MEMBER(psg_4017_w); - void state_register(); - void setup_ioports(); + NESCTRL_BRIGHTPIXEL_CB(bright_pixel); DECLARE_DRIVER_INIT(famicom); @@ -139,19 +111,6 @@ public: DECLARE_MACHINE_RESET(famitwin); void setup_disk(nes_disksys_device *slot); - // 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; - UINT8 m_powerpad_latch[2]; - UINT8 m_ftrainer_scan; - -protected: - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); - private: memory_bank *m_prg_bank_mem[5]; }; diff --git a/src/mess/machine/nes.c b/src/mess/machine/nes.c index 14ca4c6aabe..b6cf0d1d086 100644 --- a/src/mess/machine/nes.c +++ b/src/mess/machine/nes.c @@ -7,21 +7,8 @@ ****************************************************************************/ #include "emu.h" -#include "crsshair.h" #include "cpu/m6502/m6502.h" #include "includes/nes.h" -#include "imagedev/flopdrv.h" - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* Set to dump info about the inputs to the errorlog */ -#define LOG_JOY 0 - -/* Set to generate prg & chr files when the cart is loaded */ -#define SPLIT_PRG 0 -#define SPLIT_CHR 0 /*************************************************************************** FUNCTIONS @@ -44,77 +31,12 @@ void nes_state::machine_reset() m_cartslot->pcb_reset(); m_maincpu->reset(); - - memset(m_pad_latch, 0, sizeof(m_pad_latch)); - memset(m_zapper_latch, 0, sizeof(m_zapper_latch)); - m_paddle_latch = 0; - m_paddle_btn_latch = 0; } //------------------------------------------------- // machine_start //------------------------------------------------- -void nes_state::state_register() -{ - save_item(NAME(m_last_frame_flip)); - - save_pointer(NAME(m_ciram), 0x800); - - 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)); - save_item(NAME(m_powerpad_latch)); - save_item(NAME(m_ftrainer_scan)); -} - -void nes_state::setup_ioports() -{ - for (int i = 0; i < 9; i++) - { - char str[7]; - sprintf(str, "FCKEY%i", i); - m_io_fckey[i] = ioport(str); - } - for (int i = 0; i < 13; i++) - { - char str[9]; - sprintf(str, "SUBKEY%i", i); - m_io_subkey[i] = ioport(str); - } - for (int i = 0; i < 4; i++) - { - char str[8]; - sprintf(str, "PAD%i", i + 1); - m_io_pad[i] = ioport(str); - sprintf(str, "MAH%i", i); - m_io_mahjong[i] = ioport(str); - sprintf(str, "FT_COL%i", i); - m_io_ftrainer[i] = ioport(str); - } - - m_io_ctrlsel = ioport("CTRLSEL"); - m_io_exp = ioport("EXP"); - m_io_paddle = ioport("PADDLE"); - m_io_paddle_btn = ioport("PADDLE_BUTTON"); - m_io_cc_left = ioport("CC_LEFT"); - m_io_cc_right = ioport("CC_RIGHT"); - m_io_zapper1_t = ioport("ZAPPER1_T"); - m_io_zapper1_x = ioport("ZAPPER1_X"); - m_io_zapper1_y = ioport("ZAPPER1_Y"); - m_io_zapper2_t = ioport("ZAPPER2_T"); - m_io_zapper2_x = ioport("ZAPPER2_X"); - m_io_zapper2_y = ioport("ZAPPER2_Y"); - m_io_powerpad[0] = ioport("POWERPAD1"); - m_io_powerpad[1] = ioport("POWERPAD2"); - m_io_disksel = ioport("FLIPDISK"); -} - void nes_state::machine_start() { address_space &space = m_maincpu->space(AS_PROGRAM); @@ -126,7 +48,7 @@ void nes_state::machine_start() m_ciram = auto_alloc_array(machine(), UINT8, 0x800); // other pointers got set in the loading routine, because they 'belong' to the cart itself - setup_ioports(); + m_io_disksel = ioport("FLIPDISK"); if (m_cartslot && m_cartslot->m_cart) { @@ -178,7 +100,9 @@ void nes_state::machine_start() m_cartslot->m_cart->pcb_reg_postload(machine()); } - state_register(); + // register saves + save_item(NAME(m_last_frame_flip)); + save_pointer(NAME(m_ciram), 0x800); } @@ -188,518 +112,71 @@ void nes_state::machine_start() READ8_MEMBER(nes_state::nes_in0_r) { - int cfg = m_io_ctrlsel->read(); - - // Some games expect bit 6 to be set because the last entry on the data bus shows up - // in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. UINT8 ret = 0x40; - ret |= (m_pad_latch[0] & 0x01); - - // shift - m_pad_latch[0] >>= 1; - - // zapper - if ((cfg & 0x000f) == 0x0002) - { - int x = m_zapper_latch[0][1]; // x-position - int y = m_zapper_latch[0][2]; // y-position - UINT32 pix, color_base; - - // get the pixel at the gun position - pix = m_ppu->get_pixel(x, y); - - // get the color base from the ppu - color_base = m_ppu->get_colorbase(); - - // check if the cursor is over a bright pixel - if ((pix == color_base + 0x20) || (pix == color_base + 0x30) || - (pix == color_base + 0x33) || (pix == color_base + 0x34)) - ret &= ~0x08; // sprite hit - else - ret |= 0x08; // no sprite hit - - // light gun trigger - ret |= (m_zapper_latch[0][0] << 4); - } - - if (LOG_JOY) - logerror("joy 0 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); - + ret |= m_ctrl1->read_bit0(); + ret |= m_ctrl1->read_bit34(); return ret; } READ8_MEMBER(nes_state::nes_in1_r) { - int cfg = m_io_ctrlsel->read(); - - // Some games expect bit 6 to be set because the last entry on the data bus shows up - // in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there. UINT8 ret = 0x40; - ret |= (m_pad_latch[1] & 0x01); - - // shift - m_pad_latch[1] >>= 1; - - // zapper - if ((cfg & 0x00f0) == 0x0020) - { - int x = m_zapper_latch[1][1]; // x-position - int y = m_zapper_latch[1][2]; // y-position - UINT32 pix, color_base; - - // get the pixel at the gun position - pix = m_ppu->get_pixel(x, y); - - // get the color base from the ppu - color_base = m_ppu->get_colorbase(); - - // check if the cursor is over a bright pixel - if ((pix == color_base + 0x20) || (pix == color_base + 0x30) || - (pix == color_base + 0x33) || (pix == color_base + 0x34)) - ret &= ~0x08; // sprite hit - else - ret |= 0x08; // no sprite hit - - // light gun trigger - ret |= (m_zapper_latch[1][0] << 4); - } - - // arkanoid paddle - if ((cfg & 0x00f0) == 0x0040) - { - ret |= (m_paddle_btn_latch << 3); // button - ret |= ((m_paddle_latch & 0x80) >> 3); // paddle data - m_paddle_latch <<= 1; - m_paddle_latch &= 0xff; - } - - // powerpad - if ((cfg & 0x00f0) == 0x0050 || (cfg & 0x00f0) == 0x0060) - { - ret |= ((m_powerpad_latch[0] & 0x01) << 3); - ret |= ((m_powerpad_latch[1] & 0x01) << 4); - m_powerpad_latch[0] >>= 1; - m_powerpad_latch[1] >>= 1; - } - - if (LOG_JOY) - logerror("joy 1 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); - + ret |= m_ctrl2->read_bit0(); + ret |= m_ctrl2->read_bit34(); return ret; } WRITE8_MEMBER(nes_state::nes_in0_w) { - int cfg = m_io_ctrlsel->read(); - - if (LOG_JOY) - logerror("joy write, val: %02x, pc: %04x\n", data, space.device().safe_pc()); - - // Check if lightgun has been chosen as input: if so, enable crosshair - timer_set(attotime::zero, TIMER_ZAPPER_TICK); - - if (data & 0x01) - return; - - // Toggling bit 0 high then low resets controllers - m_pad_latch[0] = 0; - m_pad_latch[1] = 0; - m_zapper_latch[0][0] = 0; - m_zapper_latch[0][1] = 0; - m_zapper_latch[0][2] = 0; - m_zapper_latch[1][0] = 0; - m_zapper_latch[1][1] = 0; - m_zapper_latch[1][2] = 0; - m_paddle_btn_latch = 0; - m_paddle_latch = 0; - m_powerpad_latch[0] = 0; - m_powerpad_latch[1] = 0; - - // P1 inputs - switch (cfg & 0x000f) - { - case 0x01: // pad 1 - m_pad_latch[0] = m_io_pad[0]->read(); - break; - - case 0x02: // zapper (secondary) - m_zapper_latch[0][0] = m_io_zapper1_t->read(); - m_zapper_latch[0][1] = m_io_zapper1_x->read(); - m_zapper_latch[0][2] = m_io_zapper1_y->read(); - break; - } - - // P2 inputs - switch ((cfg & 0x00f0) >> 4) - { - case 0x01: // pad 2 - m_pad_latch[1] = m_io_pad[1]->read(); - break; - - case 0x02: // zapper (primary) - most games expect pad in port1 & zapper in port2 - m_zapper_latch[1][0] = m_io_zapper2_t->read(); - m_zapper_latch[1][1] = m_io_zapper2_x->read(); - m_zapper_latch[1][2] = m_io_zapper2_y->read(); - break; - - case 0x04: // arkanoid paddle - m_paddle_btn_latch = m_io_paddle_btn->read(); - m_paddle_latch = (UINT8) (m_io_paddle->read() ^ 0xff); - break; - - case 0x05: // power pad - case 0x06: // power pad - m_powerpad_latch[0] = m_io_powerpad[0]->read(); - m_powerpad_latch[1] = m_io_powerpad[1]->read() | 0xf0; - break; - } - - // P3 & P4 inputs in NES Four Score are read serially with P1 & P2 - // P3 inputs - if ((cfg & 0x0f00)) - m_pad_latch[0] |= ((m_io_pad[2]->read() << 8) | (0x08 << 16)); // pad 3 + signature - - // P4 inputs - if ((cfg & 0xf000)) - m_pad_latch[1] |= ((m_io_pad[3]->read() << 8) | (0x04 << 16)); // pad 4 + signature -} - - -WRITE8_MEMBER(nes_state::nes_in1_w) -{ + m_ctrl1->write(data); + m_ctrl2->write(data); } 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 - // in the unused upper 3 bits, so typically a read from $4016 leaves 0x40 there. UINT8 ret = 0x40; - ret |= (m_pad_latch[0] & 0x01); - - // shift - m_pad_latch[0] >>= 1; - - // microphone bit - if ((cfg & 0x00f0) == 0x00f0) - ret |= m_mic_obstruct; //bit2! - - // EXP input - switch (exp & 0x0f) - { - case 0x02: // FC Keyboard: tape input - if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY) - { - double level = m_cassette->input(); - if (level < 0) - ret |= 0x00; - else - ret |= 0x02; - } - break; - - case 0x04: // Arkanoid paddle - ret |= (m_paddle_btn_latch << 1); // button - break; - - case 0x07: // Mahjong Panel - ret |= ((m_mjpanel_latch & 0x01) << 1); - m_mjpanel_latch >>= 1; - break; - - case 0x08: // 'multitap' p3 - ret |= ((m_pad_latch[2] & 0x01) << 1); - m_pad_latch[2] >>= 1; - break; - } - - if (LOG_JOY) - logerror("joy 0 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); - + // bit 0 to controller port + ret |= m_ctrl1->read_bit0(); + + // expansion port bits (in the original FC, P2 controller was hooked to these lines + // too, so in principle some homebrew hardware modification could use the same + // connection with P1 controller too) + ret |= m_ctrl1->read_exp(0); + ret |= m_ctrl2->read_exp(0); + + // at the same time, we might have a standard joypad connected to the expansion port which + // shall be read as P3 (this is needed here to avoid implementing the expansion port as a + // different device compared to the standard control port... it might be changed later) + ret |= (m_exp->read_bit0() << 1); + // finally, read the expansion port as expected + ret |= m_exp->read_exp(0); return ret; } READ8_MEMBER(nes_state::fc_in1_r) { - int exp = m_io_exp->read(); - - // Some games expect bit 6 to be set because the last entry on the data bus shows up - // in the unused upper 3 bits, so typically a read from $4017 leaves 0x40 there. UINT8 ret = 0x40; - ret |= (m_pad_latch[1] & 0x01); - - // shift - m_pad_latch[1] >>= 1; - - - // EXP input - switch (exp & 0x0f) - { - case 0x01: // Lightgun - { - int x = m_zapper_latch[0][1]; // x-position - int y = m_zapper_latch[0][2]; // y-position - UINT32 pix, color_base; - - // get the pixel at the gun position - pix = m_ppu->get_pixel(x, y); - - // get the color base from the ppu - color_base = m_ppu->get_colorbase(); - - // check if the cursor is over a bright pixel - if ((pix == color_base + 0x20) || (pix == color_base + 0x30) || - (pix == color_base + 0x33) || (pix == color_base + 0x34)) - ret &= ~0x08; // sprite hit - else - ret |= 0x08; // no sprite hit - - // light gun trigger - ret |= (m_zapper_latch[0][0] << 4); - } - break; - - case 0x02: // FC Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 - if (m_fck_scan < 9) - ret |= ~(((m_io_fckey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; - else - ret |= 0x1e; - break; - - case 0x03: // Subor Keyboard: rows of the keyboard matrix are read 4-bits at time and returned as bit1->bit4 - if (m_fck_scan < 12) - ret |= ~(((m_io_subkey[m_fck_scan]->read() >> (m_fck_mode * 4)) & 0x0f) << 1) & 0x1e; - else - ret |= 0x1e; - break; - - case 0x04: // Arkanoid paddle - ret |= ((m_paddle_latch & 0x80) >> 6); // paddle data - m_paddle_latch <<= 1; - m_paddle_latch &= 0xff; - break; - - case 0x05: // family trainer - case 0x06: // family trainer - if (!BIT(m_ftrainer_scan, 0)) - { - // read low line: buttons 9,10,11,12 - for (int i = 0; i < 4; i++) - ret |= ((m_io_ftrainer[i]->read() & 0x01) << (1 + i)); - } - else if (!BIT(m_ftrainer_scan, 1)) - { - // read mid line: buttons 5,6,7,8 - for (int i = 0; i < 4; i++) - ret |= ((m_io_ftrainer[i]->read() & 0x02) << (1 + i)); - } - else if (!BIT(m_ftrainer_scan, 2)) - { - // read high line: buttons 1,2,3,4 - for (int i = 0; i < 4; i++) - ret |= ((m_io_ftrainer[i]->read() & 0x04) << (1 + i)); - } - break; - - case 0x07: // Mahjong Panel - ret |= ((m_mjpanel_latch & 0x01) << 1); - m_mjpanel_latch >>= 1; - break; - - case 0x08: // 'multitap' p4 - ret |= ((m_pad_latch[3] & 0x01) << 1); - m_pad_latch[3] >>= 1; - break; - } - - if (LOG_JOY) - logerror("joy 1 read, val: %02x, pc: %04x\n", ret, space.device().safe_pc()); - + // bit 0 to controller port + ret |= m_ctrl2->read_bit0(); + + // expansion port bits (in the original FC, P2 controller was hooked to these lines + // too, so in principle some homebrew hardware modification could use the same + // connection with P1 controller too) + ret |= m_ctrl1->read_exp(1); + ret |= m_ctrl2->read_exp(1); + + // finally, read the expansion port as expected (standard pad cannot be hooked as P4, so + // no read_bit0 here) + ret |= m_exp->read_exp(1); return ret; } WRITE8_MEMBER(nes_state::fc_in0_w) { - int cfg = m_io_ctrlsel->read(); - int exp = m_io_exp->read(); - - if (LOG_JOY) - logerror("joy write, val: %02x, pc: %04x\n", data, space.device().safe_pc()); - - // Check if lightgun has been chosen as input: if so, enable crosshair - timer_set(attotime::zero, TIMER_LIGHTGUN_TICK); - - // keyboards - if ((exp & 0x0f) == 0x02 || (exp & 0x0f) == 0x03) - { - // tape output (not fully tested) - if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD) - m_cassette->output(((data & 0x07) == 0x07) ? +1.0 : -1.0); - - if (BIT(data, 2)) // keyboard active - { - int lines = ((exp & 0x0f) == 0x02) ? 9 : 12; - UINT8 out = BIT(data, 1); // scan - - if (m_fck_mode && !out && ++m_fck_scan > lines) - m_fck_scan = 0; - - m_fck_mode = out; // access lower or upper 4 bits - - if (BIT(data, 0)) // reset - m_fck_scan = 0; - } - } - - // family trainer - if ((exp & 0x0f) == 0x05 || (exp & 0x0f) == 0x06) - { - // select raw to scan - m_ftrainer_scan = data & 0x07; - } - - if (data & 0x01) - return; - - // Toggling bit 0 high then low resets controllers - m_pad_latch[0] = 0; - m_pad_latch[1] = 0; - m_pad_latch[2] = 0; - m_pad_latch[3] = 0; - m_zapper_latch[0][0] = 0; - m_zapper_latch[0][1] = 0; - m_zapper_latch[0][2] = 0; - m_paddle_btn_latch = 0; - m_paddle_latch = 0; - m_mjpanel_latch = 0; - m_mic_obstruct = 0; - - // P1 inputs - switch (cfg & 0x000f) - { - case 0x01: // pad 1 - m_pad_latch[0] = m_io_pad[0]->read(); - break; - - case 0x02: // crazy climber (left stick) - m_pad_latch[0] = m_io_cc_left->read(); - break; - } - - // P2 inputs - switch ((cfg & 0x00f0) >> 4) - { - case 0x01: // pad 2 - m_pad_latch[1] = m_io_pad[1]->read(); - break; - - case 0x02: // crazy climber (right stick) - 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) - // are read in parallel with P1 & P2 (just using diff bits) - // P3 inputs - if ((exp & 0x0f) == 8 && (cfg & 0x0f00) == 0x0100) - m_pad_latch[2] = m_io_pad[2]->read(); // pad 3 - - // P4 inputs - if ((exp & 0x0f) == 8 && (cfg & 0xf000) == 0x1000) - m_pad_latch[3] = m_io_pad[3]->read(); // pad 4 - - - // EXP input - switch (exp & 0x0f) - { - case 0x01: // Lightgun - m_zapper_latch[0][0] = m_io_zapper2_t->read(); - m_zapper_latch[0][1] = m_io_zapper2_x->read(); - m_zapper_latch[0][2] = m_io_zapper2_y->read(); - break; - - case 0x02: // FC Keyboard - case 0x03: // Subor Keyboard - // these are scanned differently than other devices: - // writes to $4016 with bit2 set always update the - // line counter and writing bit0 set resets the counter - break; - - case 0x04: // Arkanoid paddle - m_paddle_btn_latch = m_io_paddle_btn->read(); - m_paddle_latch = (UINT8) (m_io_paddle->read() ^ 0xff); - break; - - case 0x05: // family trainer - case 0x06: // family trainer - // these are scanned differently than other devices: - // bit0-bit2 of writes to $4016 select the row to read - // from from the mat input "columns" - break; - - - case 0x07: // Mahjong Panel - if (data & 0xf8) - logerror("Error: Mahjong panel read with mux data %02x\n", (data & 0xfe)); - else - m_mjpanel_latch = m_io_mahjong[(data & 0xfe) >> 1]->read(); - break; - } - -} - - -void nes_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_ZAPPER_TICK: - if ((m_io_ctrlsel->read() & 0x000f) == 0x0002) - { - /* enable lightpen crosshair */ - crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); - } - else - { - /* disable lightpen crosshair */ - crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE); - } - - if ((m_io_ctrlsel->read() & 0x00f0) == 0x0020) - { - /* enable lightpen crosshair */ - crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL); - } - else - { - /* disable lightpen crosshair */ - crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_NONE); - } - break; - case TIMER_LIGHTGUN_TICK: - if ((m_io_exp->read() & 0x0f) == 0x01) - { - /* enable lightpen crosshair */ - crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); - } - else - { - /* disable lightpen crosshair */ - crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE); - } - break; - default: - assert_always(FALSE, "Unknown id in nes_state::device_timer"); - } + m_ctrl1->write(data); + m_ctrl2->write(data); + m_exp->write(data); } @@ -711,3 +188,19 @@ DRIVER_INIT_MEMBER(nes_state,famicom) space.install_write_handler(0x4016, 0x4016, write8_delegate(FUNC(nes_state::fc_in0_w), this)); space.install_read_handler(0x4017, 0x4017, read8_delegate(FUNC(nes_state::fc_in1_r), this)); } + +NESCTRL_BRIGHTPIXEL_CB(nes_state::bright_pixel) +{ + // get the pixel at the gun position + UINT32 pix = m_ppu->get_pixel(x, y); + + // get the color base from the ppu + UINT32 color_base = m_ppu->get_colorbase(); + + // check if the cursor is over a bright pixel + if ((pix == color_base + 0x20) || (pix == color_base + 0x30) || + (pix == color_base + 0x33) || (pix == color_base + 0x34)) + return true; + else + return false; +} diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 13ae90f2b22..c454f79059f 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -614,6 +614,7 @@ BUSES += MEGADRIVE BUSES += MSX_SLOT BUSES += NEOGEO BUSES += NES +BUSES += NES_CTRL BUSES += NUBUS BUSES += O2 BUSES += ORICEXT |