diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 8c42031dbf2..01dd5b214d9 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3047,6 +3047,14 @@ if (BUSES["NES_CTRL"]~=null) then MAME_DIR .. "src/devices/bus/nes_ctrl/zapper.cpp", MAME_DIR .. "src/devices/bus/nes_ctrl/zapper.h", } + + dependency { + { MAME_DIR .. "src/devices/bus/nes_ctrl/zapper.cpp", GEN_DIR .. "emu/layout/nes_rob.lh" }, + } + + custombuildtask { + layoutbuildtask("emu/layout", "nes_rob"), + } end --------------------------------------------------- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 86ef561f620..1020f45a1c6 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -138,7 +138,7 @@ CPUS["HMCS40"] = true --CPUS["E0C6200"] = true --CPUS["MELPS4"] = true --CPUS["HPHYBRID"] = true ---CPUS["SM510"] = true +CPUS["SM510"] = true CPUS["ST62XX"] = true CPUS["DSPP"] = true CPUS["HPC"] = true diff --git a/src/devices/bus/nes_ctrl/ctrl.cpp b/src/devices/bus/nes_ctrl/ctrl.cpp index 57d12e28cfe..16c595b9ae3 100644 --- a/src/devices/bus/nes_ctrl/ctrl.cpp +++ b/src/devices/bus/nes_ctrl/ctrl.cpp @@ -199,6 +199,11 @@ void nes_control_port2_devices(device_slot_interface &device) device.option_add("vboy", NES_VBOYCTRL); } +void nes_control_special_devices(device_slot_interface &device) +{ + device.option_add("rob", NES_ROB); +} + void fc_control_port1_devices(device_slot_interface &device) { device.option_add("joypad", NES_JOYPAD); diff --git a/src/devices/bus/nes_ctrl/ctrl.h b/src/devices/bus/nes_ctrl/ctrl.h index 4b11084a393..f404e5c660f 100644 --- a/src/devices/bus/nes_ctrl/ctrl.h +++ b/src/devices/bus/nes_ctrl/ctrl.h @@ -94,6 +94,7 @@ DECLARE_DEVICE_TYPE(NES_CONTROL_PORT, nes_control_port_device) void nes_control_port1_devices(device_slot_interface &device); void nes_control_port2_devices(device_slot_interface &device); +void nes_control_special_devices(device_slot_interface &device); void fc_control_port1_devices(device_slot_interface &device); void fc_control_port2_devices(device_slot_interface &device); void fc_expansion_devices(device_slot_interface &device); diff --git a/src/devices/bus/nes_ctrl/zapper.cpp b/src/devices/bus/nes_ctrl/zapper.cpp index e655ec233ff..4906db2ce7a 100644 --- a/src/devices/bus/nes_ctrl/zapper.cpp +++ b/src/devices/bus/nes_ctrl/zapper.cpp @@ -4,6 +4,17 @@ Nintendo Family Computer & Entertainment System Zapper Lightgun Nintendo Family Computer Bandai Hyper Shot Lightgun + Nintendo R.O.B. + + TODO: + - nes_rob is in here because it needs the zapper light sensor, + in reality it's not connected to the control port at all, but how + would it be interfaced with the NES driver otherwise? + - does nes_rob have motor sensors? (eg. limit switches, or optical + sensor to determine position) + - can't really play anything with nes_rob, because of interaction + with physical objects (gyromite especially, since it has a gadget + to make the robot press joypad buttons) **********************************************************************/ @@ -11,12 +22,15 @@ #include "screen.h" #include "zapper.h" +#include "nes_rob.lh" + //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** -DEFINE_DEVICE_TYPE(NES_ZAPPER, nes_zapper_device, "nes_zapper", "Nintendo Zapper Lightgun") +DEFINE_DEVICE_TYPE(NES_ZAPPER, nes_zapper_device, "nes_zapper", "Nintendo Zapper Lightgun") DEFINE_DEVICE_TYPE(NES_BANDAIHS, nes_bandaihs_device, "nes_bandaihs", "Bandai Hyper Shot Lightgun") +DEFINE_DEVICE_TYPE(NES_ROB, nes_rob_device, "nes_rob", "Nintendo R.O.B.") static INPUT_PORTS_START( nes_zapper ) @@ -33,7 +47,7 @@ static INPUT_PORTS_START( nes_bandaihs ) PORT_INCLUDE( nes_zapper ) PORT_START("JOYPAD") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // has complete joypad inputs except button A + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) // has complete joypad inputs except button A PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("%p B") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) @@ -44,6 +58,15 @@ static INPUT_PORTS_START( nes_bandaihs ) INPUT_PORTS_END +static INPUT_PORTS_START( nes_rob ) + PORT_INCLUDE( nes_zapper ) + + // it has the x/y for aiming the 'eyes', but there is no lightgun trigger + PORT_MODIFY("ZAPPER_T") + PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) +INPUT_PORTS_END + + //------------------------------------------------- // input_ports - device-specific input ports //------------------------------------------------- @@ -58,6 +81,10 @@ ioport_constructor nes_bandaihs_device::device_input_ports() const return INPUT_PORTS_NAME( nes_bandaihs ); } +ioport_constructor nes_rob_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_rob ); +} //************************************************************************** @@ -89,6 +116,14 @@ nes_bandaihs_device::nes_bandaihs_device(const machine_config &mconfig, const ch { } +nes_rob_device::nes_rob_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_zapper_device(mconfig, NES_ROB, tag, owner, clock) + , m_maincpu(*this, "maincpu") + , m_motor_out(*this, "rob_motor.%u", 0U) + , m_led_out(*this, "rob_led") +{ +} + //------------------------------------------------- // device_start @@ -105,6 +140,15 @@ void nes_bandaihs_device::device_start() save_item(NAME(m_strobe)); } +void nes_rob_device::device_start() +{ + nes_zapper_device::device_start(); + + // resolve handlers + m_motor_out.resolve(); + m_led_out.resolve(); +} + //------------------------------------------------- // read @@ -192,3 +236,63 @@ void nes_bandaihs_device::write(u8 data) if (write_strobe(data)) m_latch = m_joypad->read(); } + + +//------------------------------------------------- +// R.O.B. specific handlers +//------------------------------------------------- + +u8 nes_rob_device::input_r() +{ + // R00: lightsensor + return (read_bit34() & 8) ? 1 : 0; +} + +void nes_rob_device::output_w(offs_t offset, u8 data) +{ + switch (offset & 3) + { + case 0: + // R03: led + m_led_out = BIT(data, 3); + break; + + case 1: + // R10-R13: motors: down, up, close, open + for (int i = 0; i < 4; i++) + m_motor_out[i] = BIT(data, i); + break; + + case 2: + // R20,R21: motors: right, left + for (int i = 0; i < 2; i++) + m_motor_out[i + 4] = BIT(data, i); + break; + + default: + break; + } +} + +void nes_rob_device::device_add_mconfig(machine_config &config) +{ + SM590(config, m_maincpu, 455_kHz_XTAL); + m_maincpu->read_r<0>().set(FUNC(nes_rob_device::input_r)); + m_maincpu->write_r<0>().set(FUNC(nes_rob_device::output_w)); + m_maincpu->write_r<1>().set(FUNC(nes_rob_device::output_w)); + m_maincpu->write_r<2>().set(FUNC(nes_rob_device::output_w)); + m_maincpu->write_r<3>().set(FUNC(nes_rob_device::output_w)); + + // must use -numscreens 2 to see the output status + config.set_default_layout(layout_nes_rob); +} + +ROM_START( nes_rob ) + ROM_REGION( 0x200, "maincpu", 0 ) + ROM_LOAD( "rfc-cpu10.ic1", 0x000, 0x200, CRC(f9c96b9c) SHA1(a87e2f0f5e454c093d1352ac368aa9e82e9f6790) ) +ROM_END + +const tiny_rom_entry *nes_rob_device::device_rom_region() const +{ + return ROM_NAME(nes_rob); +} diff --git a/src/devices/bus/nes_ctrl/zapper.h b/src/devices/bus/nes_ctrl/zapper.h index 943fb920cdd..3761ecd7583 100644 --- a/src/devices/bus/nes_ctrl/zapper.h +++ b/src/devices/bus/nes_ctrl/zapper.h @@ -4,6 +4,7 @@ Nintendo Family Computer & Entertainment System Zapper Lightgun Nintendo Family Computer Bandai Hyper Shot Lightgun + Nintendo R.O.B. **********************************************************************/ @@ -14,6 +15,7 @@ #include "ctrl.h" +#include "cpu/sm510/sm590.h" //************************************************************************** // TYPE DEFINITIONS @@ -70,8 +72,37 @@ private: }; +// ======================> nes_rob_device + +class nes_rob_device : public nes_zapper_device +{ +public: + // construction/destruction + nes_rob_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual ioport_constructor device_input_ports() const override; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual u8 read_exp(offs_t offset) override { return 0; } + +private: + required_device m_maincpu; + output_finder<6> m_motor_out; + output_finder<> m_led_out; + + u8 input_r(); + void output_w(offs_t offset, u8 data); +}; + + // device type definition -DECLARE_DEVICE_TYPE(NES_ZAPPER, nes_zapper_device) +DECLARE_DEVICE_TYPE(NES_ZAPPER, nes_zapper_device) DECLARE_DEVICE_TYPE(NES_BANDAIHS, nes_bandaihs_device) +DECLARE_DEVICE_TYPE(NES_ROB, nes_rob_device) #endif // MAME_BUS_NES_CTRL_ZAPPER diff --git a/src/devices/cpu/sm510/sm590op.cpp b/src/devices/cpu/sm510/sm590op.cpp index a539c4bd061..9c43f9250b4 100644 --- a/src/devices/cpu/sm510/sm590op.cpp +++ b/src/devices/cpu/sm510/sm590op.cpp @@ -168,5 +168,5 @@ void sm590_device::op_rta() { // RTA: load ACC with R(BL) u8 offset = m_bl & 3; - m_acc = (m_rports[offset] | m_read_rx[offset]()) & 0xf; + m_acc = (m_rports[offset] | m_read_rx[offset](offset)) & 0xf; } diff --git a/src/emu/layout/nes_rob.lay b/src/emu/layout/nes_rob.lay new file mode 100644 index 00000000000..c1a733f177e --- /dev/null +++ b/src/emu/layout/nes_rob.lay @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/drivers/nes.cpp b/src/mame/drivers/nes.cpp index f3b4fe7a532..303ef932de7 100644 --- a/src/mame/drivers/nes.cpp +++ b/src/mame/drivers/nes.cpp @@ -75,10 +75,9 @@ void nes_state::nes(machine_config &config) SPEAKER(config, "mono").front_center(); maincpu.add_route(ALL_OUTPUTS, "mono", 0.90); - NES_CONTROL_PORT(config, m_ctrl1, nes_control_port1_devices, "joypad"); - NES_CONTROL_PORT(config, m_ctrl2, nes_control_port2_devices, "joypad"); - m_ctrl1->set_screen_tag(m_screen); - m_ctrl2->set_screen_tag(m_screen); + NES_CONTROL_PORT(config, m_ctrl1, nes_control_port1_devices, "joypad").set_screen_tag(m_screen); + NES_CONTROL_PORT(config, m_ctrl2, nes_control_port2_devices, "joypad").set_screen_tag(m_screen); + NES_CONTROL_PORT(config, m_special, nes_control_special_devices, nullptr).set_screen_tag(m_screen); NES_CART_SLOT(config, m_cartslot, NTSC_APU_CLOCK, nes_cart, nullptr).set_must_be_loaded(true); SOFTWARE_LIST(config, "cart_list").set_original("nes"); @@ -113,12 +112,9 @@ void nes_state::famicom(machine_config &config) { nes(config); - NES_CONTROL_PORT(config.replace(), m_ctrl1, fc_control_port1_devices, "joypad"); - NES_CONTROL_PORT(config.replace(), m_ctrl2, fc_control_port2_devices, "joypad"); - NES_CONTROL_PORT(config, m_exp, fc_expansion_devices, nullptr); - m_ctrl1->set_screen_tag(m_screen); - m_ctrl2->set_screen_tag(m_screen); - m_exp->set_screen_tag(m_screen); + NES_CONTROL_PORT(config.replace(), m_ctrl1, fc_control_port1_devices, "joypad").set_screen_tag(m_screen); + NES_CONTROL_PORT(config.replace(), m_ctrl2, fc_control_port2_devices, "joypad").set_screen_tag(m_screen); + NES_CONTROL_PORT(config, m_exp, fc_expansion_devices, nullptr).set_screen_tag(m_screen); SOFTWARE_LIST(config, "flop_list").set_original("famicom_flop"); SOFTWARE_LIST(config, "cass_list").set_original("famicom_cass"); @@ -148,12 +144,9 @@ void nes_state::famipalc(machine_config &config) { nespalc(config); - NES_CONTROL_PORT(config.replace(), m_ctrl1, fc_control_port1_devices, "joypad"); - NES_CONTROL_PORT(config.replace(), m_ctrl2, fc_control_port2_devices, "joypad"); - NES_CONTROL_PORT(config, m_exp, fc_expansion_devices, nullptr); - m_ctrl1->set_screen_tag(m_screen); - m_ctrl2->set_screen_tag(m_screen); - m_exp->set_screen_tag(m_screen); + NES_CONTROL_PORT(config.replace(), m_ctrl1, fc_control_port1_devices, "joypad").set_screen_tag(m_screen); + NES_CONTROL_PORT(config.replace(), m_ctrl2, fc_control_port2_devices, "joypad").set_screen_tag(m_screen); + NES_CONTROL_PORT(config, m_exp, fc_expansion_devices, nullptr).set_screen_tag(m_screen); SOFTWARE_LIST(config, "cass_list").set_original("famicom_cass"); } diff --git a/src/mame/includes/nes.h b/src/mame/includes/nes.h index 5360925f084..2d82b32e194 100644 --- a/src/mame/includes/nes.h +++ b/src/mame/includes/nes.h @@ -53,15 +53,14 @@ public: m_ppu(*this, "ppu"), m_screen(*this, "screen"), m_exp(*this, "exp"), + m_special(*this, "special"), m_cartslot(*this, "nes_slot"), m_disk(*this, "disk"), m_prg_bank(*this, "prg%u", 0U) { } - int nes_ppu_vidaccess(int address, int data); - uint8_t fc_in0_r(); uint8_t fc_in1_r(); void fc_in0_w(uint8_t data); @@ -91,6 +90,7 @@ public: void nes(machine_config &config); void fds(machine_config &config); void nes_map(address_map &map); + private: // video-related int m_last_frame_flip; @@ -105,6 +105,7 @@ private: required_device m_ppu; required_device m_screen; optional_device m_exp; + optional_device m_special; optional_device m_cartslot; optional_device m_disk; memory_bank_array_creator<4> m_prg_bank;