nes: added R.O.B.

This commit is contained in:
hap 2022-03-15 00:10:17 +01:00
parent f1f36c9ba0
commit 5efd366143
10 changed files with 229 additions and 23 deletions

View File

@ -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
---------------------------------------------------

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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_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 )
@ -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);
}

View File

@ -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<sm590_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_BANDAIHS, nes_bandaihs_device)
DECLARE_DEVICE_TYPE(NES_ROB, nes_rob_device)
#endif // MAME_BUS_NES_CTRL_ZAPPER

View File

@ -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;
}

View File

@ -0,0 +1,63 @@
<?xml version="1.0"?>
<!--
license:CC0
-->
<mamelayout version="2">
<!-- define elements -->
<element name="text_m1"><text align="1" string="motor 1:"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_m2"><text align="1" string="motor 2:"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="text_m3"><text align="1" string="motor 3:"><color red="0.8" green="0.8" blue="0.8" /></text></element>
<element name="mstatus0">
<text state="1" align="1" string="DOWN"><color red="1.0" green="1.0" blue="0.2" /></text>
<text state="0" align="1" string="DOWN"><color red="0.2" green="0.2" blue="0.2" /></text>
</element>
<element name="mstatus1">
<text state="1" align="1" string="UP"><color red="1.0" green="1.0" blue="0.2" /></text>
<text state="0" align="1" string="UP"><color red="0.2" green="0.2" blue="0.2" /></text>
</element>
<element name="mstatus2">
<text state="1" align="1" string="CLOSE"><color red="1.0" green="1.0" blue="0.2" /></text>
<text state="0" align="1" string="CLOSE"><color red="0.2" green="0.2" blue="0.2" /></text>
</element>
<element name="mstatus3">
<text state="1" align="1" string="OPEN"><color red="1.0" green="1.0" blue="0.2" /></text>
<text state="0" align="1" string="OPEN"><color red="0.2" green="0.2" blue="0.2" /></text>
</element>
<element name="mstatus4">
<text state="1" align="1" string="RIGHT"><color red="1.0" green="1.0" blue="0.2" /></text>
<text state="0" align="1" string="RIGHT"><color red="0.2" green="0.2" blue="0.2" /></text>
</element>
<element name="mstatus5">
<text state="1" align="1" string="LEFT"><color red="1.0" green="1.0" blue="0.2" /></text>
<text state="0" align="1" string="LEFT"><color red="0.2" green="0.2" blue="0.2" /></text>
</element>
<element name="led" defstate="0">
<disk state="1"><color red="1.0" green="0.1" blue="0.15" /></disk>
<disk state="0"><color red="0.15" green="0.015" blue="0.017" /></disk>
</element>
<!-- build screen -->
<view name="Internal Layout">
<bounds left="4" right="17" top="6" bottom="15" />
<element ref="text_m1"><bounds x="5.5" y="10" width="5" height="1" /></element>
<element ref="text_m2"><bounds x="5.5" y="11.5" width="5" height="1" /></element>
<element ref="text_m3"><bounds x="5.5" y="13" width="5" height="1" /></element>
<element name="rob_motor.1" ref="mstatus1"><bounds x="10" y="10" width="5" height="1" /></element>
<element name="rob_motor.0" ref="mstatus0"><bounds x="13.5" y="10" width="5" height="1" /></element>
<element name="rob_motor.5" ref="mstatus5"><bounds x="10" y="11.5" width="5" height="1" /></element>
<element name="rob_motor.4" ref="mstatus4"><bounds x="13.5" y="11.5" width="5" height="1" /></element>
<element name="rob_motor.2" ref="mstatus2"><bounds x="10" y="13" width="5" height="1" /></element>
<element name="rob_motor.3" ref="mstatus3"><bounds x="13.5" y="13" width="5" height="1" /></element>
<element name="rob_led" ref="led"><bounds x="10" y="7" width="1" height="1" /></element>
</view>
</mamelayout>

View File

@ -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");
}

View File

@ -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<ppu2c0x_device> m_ppu;
required_device<screen_device> m_screen;
optional_device<nes_control_port_device> m_exp;
optional_device<nes_control_port_device> m_special;
optional_device<nes_cart_slot_device> m_cartslot;
optional_device<nes_disksys_device> m_disk;
memory_bank_array_creator<4> m_prg_bank;