summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/talkingfb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/talkingfb.cpp')
-rw-r--r--src/mame/drivers/talkingfb.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/mame/drivers/talkingfb.cpp b/src/mame/drivers/talkingfb.cpp
new file mode 100644
index 00000000000..b1070044ea4
--- /dev/null
+++ b/src/mame/drivers/talkingfb.cpp
@@ -0,0 +1,264 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+// thanks-to:Kevin Horton
+/******************************************************************************
+
+Parker Brothers Superstar Lineup Talking Football
+
+Hardware notes:
+- PCB label KPT-410 REV B1 (*KPT = Kenner Parker Toys)
+- 80C31 MCU @ 12MHz
+- 2KB RAM, 256KB ROM, 2 cartridge slots
+- two 20-button keypads
+
+Like Baseball, The ROM chip has (C) Tonka.
+The speech driver is by Mozer, the ROM data includes employees names.
+
+The cartridge slots are probably meant for extra teams. I can't find anything
+about it in the manual or any proof that cartridges were released for this.
+Maybe the toy went out of production soon after release.
+
+The game includes formation cards, refer to the manual on which number is which strategy.
+
+TODO:
+- add cartridge slots (no need if no carts exist?)
+- verify keypad (everything seems ok, but "Pursue" and "Go For Turnover" might
+ be swapped, their function is nearly identical so it's hard to test)
+
+******************************************************************************/
+
+#include "emu.h"
+#include "cpu/mcs51/mcs51.h"
+#include "sound/dac.h"
+#include "sound/volt_reg.h"
+#include "speaker.h"
+
+
+namespace {
+
+class talkingfb_state : public driver_device
+{
+public:
+ talkingfb_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_rom(*this, "maincpu"),
+ m_inputs(*this, "IN.%u", 0)
+ { }
+
+ void talkingfb(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+
+private:
+ // devices/pointers
+ required_device<mcs51_cpu_device> m_maincpu;
+ required_region_ptr<u8> m_rom;
+ required_ioport_array<5> m_inputs;
+
+ void main_map(address_map &map);
+ void main_io(address_map &map);
+
+ u8 m_bank;
+ u8 m_inp_mux;
+
+ // I/O handlers
+ DECLARE_WRITE8_MEMBER(bank_w);
+ template<int Psen> DECLARE_READ8_MEMBER(bank_r);
+ DECLARE_WRITE8_MEMBER(input_w);
+ DECLARE_READ8_MEMBER(input_r);
+};
+
+void talkingfb_state::machine_start()
+{
+ // zerofill
+ m_bank = 0;
+ m_inp_mux = 0;
+
+ // register for savestates
+ save_item(NAME(m_bank));
+ save_item(NAME(m_inp_mux));
+}
+
+
+
+/******************************************************************************
+ I/O
+******************************************************************************/
+
+WRITE8_MEMBER(talkingfb_state::bank_w)
+{
+ // d0-d2: upper rom bank
+ // d3-d5: upper rom enable (bus conflict possible)
+ // d3: cart slot 1, d4: cart slot 2, d5: internal rom
+ m_bank = data;
+}
+
+template<int Psen>
+READ8_MEMBER(talkingfb_state::bank_r)
+{
+ u32 hi = (m_bank & 7) << 15;
+ u8 data = (m_bank & 0x20) ? 0xff : m_rom[offset | hi];
+
+ // cartridge slots are only enabled if PSEN is high
+ // TODO
+
+ return data;
+}
+
+WRITE8_MEMBER(talkingfb_state::input_w)
+{
+ // d3-d7: input mux
+ m_inp_mux = data >> 3;
+}
+
+READ8_MEMBER(talkingfb_state::input_r)
+{
+ u8 data = 0;
+
+ // multiplexed inputs
+ for (int i = 0; i < 5; i++)
+ if (BIT(~m_inp_mux, i))
+ data |= m_inputs[i]->read();
+
+ return ~data;
+}
+
+
+
+/******************************************************************************
+ Address Maps
+******************************************************************************/
+
+void talkingfb_state::main_map(address_map &map)
+{
+ map(0x0000, 0x7fff).rom();
+ map(0x8000, 0xffff).r(FUNC(talkingfb_state::bank_r<0>));
+}
+
+void talkingfb_state::main_io(address_map &map)
+{
+ map(0x0000, 0x07ff).mirror(0x3800).ram();
+ map(0x4000, 0x4000).mirror(0x3fff).rw(FUNC(talkingfb_state::input_r), FUNC(talkingfb_state::input_w));
+ map(0x8000, 0xffff).r(FUNC(talkingfb_state::bank_r<1>));
+}
+
+
+
+/******************************************************************************
+ Input Ports
+******************************************************************************/
+
+/* keypad layout is like this: (P1 = Home, P2 = Away, both keypads are same)
+
+OFFENSIVE [1 [2 [3 DEFENSIVE
+ ACTION HB] FB] ST] ACTION
+
+[SCRAM/ [SCORE] [4 [5 [6 [PURSUE]
+ EVADE] FL] WR] TE]
+
+[PASS OUT/ [TIME [7] [8 [9] [GO FOR
+ RUN OUT] OUT] SE] TURNOVER]
+
+[CHECK OFF [REPLAY] [YES/ [0 [NO/
+ TO BACK] ENTER] DEMO] CANCEL]
+
+*/
+
+static INPUT_PORTS_START( talkingfb )
+ PORT_START("IN.0")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("P2 Pursue")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("P2 Scram / Evade")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) PORT_NAME("P2 Pass Out / Run Out")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("P2 Check Off To Back")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("P1 Pursue")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("P1 Scram / Evade")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) PORT_NAME("P1 Pass Out / Run Out")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) PORT_NAME("P1 Check Off To Back")
+
+ PORT_START("IN.1")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("P2 Go For Turnover")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("P2 Score")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_J) PORT_NAME("P2 Time Out")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_K) PORT_NAME("P2 Replay")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_X) PORT_NAME("P1 Go For Turnover")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("P1 Score")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("P1 Time Out")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_D) PORT_NAME("P1 Replay")
+
+ PORT_START("IN.2")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("P2 1 / HB")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("P2 4 / FL")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("P2 7")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("P2 Yes / Enter")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_NAME("P1 1 / HB")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_NAME("P1 4 / FL")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_NAME("P1 7")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("P1 Yes / Enter")
+
+ PORT_START("IN.3")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("P2 2 / FB")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("P2 5 / WR")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("P2 8 / SE")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("P2 0 / Demo")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_NAME("P1 2 / FB")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_NAME("P1 5 / WR")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_NAME("P1 8 / SE")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_NAME("P1 0 / Demo")
+
+ PORT_START("IN.4")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("P2 3 / ST")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("P2 6 / TE")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("P2 9")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("P2 No / Cancel")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_NAME("P1 3 / ST")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_NAME("P1 6 / TE")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_NAME("P1 9")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("P1 No / Cancel")
+INPUT_PORTS_END
+
+
+
+/******************************************************************************
+ Machine Configs
+******************************************************************************/
+
+void talkingfb_state::talkingfb(machine_config &config)
+{
+ /* basic machine hardware */
+ I80C31(config, m_maincpu, 12_MHz_XTAL);
+ m_maincpu->set_addrmap(AS_PROGRAM, &talkingfb_state::main_map);
+ m_maincpu->set_addrmap(AS_IO, &talkingfb_state::main_io);
+ m_maincpu->port_out_cb<1>().set("dac", FUNC(dac_8bit_r2r_device::write));
+ m_maincpu->port_out_cb<3>().set(FUNC(talkingfb_state::bank_w));
+
+ /* sound hardware */
+ SPEAKER(config, "speaker").front_center();
+ DAC_8BIT_R2R(config, "dac").add_route(ALL_OUTPUTS, "speaker", 0.5);
+ voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref"));
+ vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);
+ vref.add_route(0, "dac", -1.0, DAC_VREF_NEG_INPUT);
+}
+
+
+
+/******************************************************************************
+ ROM Definitions
+******************************************************************************/
+
+ROM_START( talkingfb )
+ ROM_REGION( 0x40000, "maincpu", 0 )
+ ROM_LOAD("sp17492-001", 0x0000, 0x40000, CRC(d03851c6) SHA1(e8ac9c342bee987657c3c18f24d466b3906d6fb0) ) // Sharp LH532378
+ROM_END
+
+} // anonymous namespace
+
+
+
+/******************************************************************************
+ Drivers
+******************************************************************************/
+
+// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
+CONS( 1989, talkingfb, 0, 0, talkingfb, talkingfb, talkingfb_state, empty_init, "Parker Brothers", "Superstar Lineup Talking Football", MACHINE_SUPPORTS_SAVE )