summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/fidel_vcc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/fidel_vcc.cpp')
-rw-r--r--src/mame/drivers/fidel_vcc.cpp414
1 files changed, 414 insertions, 0 deletions
diff --git a/src/mame/drivers/fidel_vcc.cpp b/src/mame/drivers/fidel_vcc.cpp
new file mode 100644
index 00000000000..d07bdffd706
--- /dev/null
+++ b/src/mame/drivers/fidel_vcc.cpp
@@ -0,0 +1,414 @@
+// license:BSD-3-Clause
+// copyright-holders:Kevin Horton,Jonathan Gevaryahu,Sandro Ronco,hap
+/******************************************************************************
+
+Fidelity Voice Chess Challenger series hardware
+- Voice Chess Challenger (VCC) (version A and B?)
+- Advanced Voice Chess Challenger (UVC)
+- *Grandmaster Voice Chess Challenger
+- *Decorator Challenger (FCC)
+
+*: not dumped yet
+
+*******************************************************************************
+
+RE notes by Kevin Horton
+
+The CPU is a Z80 running at 4MHz. The TSI chip runs at around 25KHz, using a
+470K / 100pf RC network. This system is very very basic, and is composed of just
+the Z80, 4 ROMs, the TSI chip, and an 8255.
+
+The Z80's interrupt inputs are all pulled to VCC, so no interrupts are used.
+
+Reset is connected to a power-on reset circuit and a button on the keypad (marked RE).
+
+The TSI chip connects to a 4K ROM. All of the 'Voiced' Chess Challengers
+use this same ROM (three or four). The later chess boards use a slightly different part
+number, but the contents are identical.
+
+Memory map (VCC):
+-----------
+0000-0FFF: 4K 2332 ROM 101-32013
+1000-1FFF: 4K 2332 ROM VCC2
+2000-2FFF: 4K 2332 ROM VCC3
+4000-5FFF: 1K RAM (2114 SRAM x2)
+6000-FFFF: empty
+
+Memory map (UVC):
+-----------
+0000-1FFF: 8K 2364 ROM 101-64017
+2000-2FFF: 4K 2332 ROM 101-32010
+4000-5FFF: 1K RAM (2114 SRAM x2)
+6000-FFFF: empty
+
+Port map:
+---------
+00-03: 8255 port chip, mirrored over the 00-FF range; program accesses F4-F7
+
+8255 connections:
+-----------------
+PA.0 - segment G, TSI A0 (W)
+PA.1 - segment F, TSI A1 (W)
+PA.2 - segment E, TSI A2 (W)
+PA.3 - segment D, TSI A3 (W)
+PA.4 - segment C, TSI A4 (W)
+PA.5 - segment B, TSI A5 (W)
+PA.6 - segment A, language latch Data (W)
+PA.7 - TSI START line, language latch clock (W, see below)
+
+PB.0 - dot commons (W)
+PB.1 - NC
+PB.2 - digit 0, bottom dot (W)
+PB.3 - digit 1, top dot (W)
+PB.4 - digit 2 (W)
+PB.5 - digit 3 (W)
+PB.6 - enable language switches (W, see below)
+PB.7 - TSI BUSY line (R)
+
+(button rows pulled up to 5V through 2.2K resistors)
+PC.0 - button row 0, German language jumper (R)
+PC.1 - button row 1, French language jumper (R)
+PC.2 - button row 2, Spanish language jumper (R)
+PC.3 - button row 3, special language jumper (R)
+PC.4 - button column A (W)
+PC.5 - button column B (W)
+PC.6 - button column C (W)
+PC.7 - button column D (W)
+
+language switches:
+------------------
+When PB.6 is pulled low, the language switches can be read. There are four.
+They connect to the button rows. When enabled, the row(s) will read low if
+the jumper is present. English only VCC's do not have the 367 or any pads stuffed.
+The jumpers are labeled: French, German, Spanish, and special.
+
+language latch:
+---------------
+There's an unstuffed 7474 on the board that connects to PA.6 and PA.7. It allows
+one to latch the state of A12 to the speech ROM. The English version has the chip
+missing, and a jumper pulling "A12" to ground. This line is really a negative
+enable.
+
+To make the VCC multi-language, one would install the 74367 (note: it must be a 74367
+or possibly a 74LS367. A 74HC367 would not work since they rely on the input current
+to keep the inputs pulled up), solder a piggybacked ROM to the existing English
+speech ROM, and finally install a 7474 dual flipflop.
+
+This way, the game can then detect which secondary language is present, and then it can
+automatically select the correct ROM(s). I have to test whether it will do automatic
+determination and give you a language option on power up or something.
+
+******************************************************************************/
+
+#include "emu.h"
+#include "includes/fidelbase.h"
+
+#include "cpu/z80/z80.h"
+#include "machine/i8255.h"
+#include "speaker.h"
+
+// internal artwork
+#include "fidel_vcc.lh" // clickable
+
+
+namespace {
+
+class vcc_state : public fidelbase_state
+{
+public:
+ vcc_state(const machine_config &mconfig, device_type type, const char *tag) :
+ fidelbase_state(mconfig, type, tag),
+ m_ppi8255(*this, "ppi8255")
+ { }
+
+ void vcc(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+
+private:
+ // devices/pointers
+ required_device<i8255_device> m_ppi8255;
+
+ // address maps
+ void main_map(address_map &map);
+ void main_io(address_map &map);
+
+ // I/O handlers
+ void prepare_display();
+ DECLARE_READ8_MEMBER(speech_r);
+ DECLARE_WRITE8_MEMBER(ppi_porta_w);
+ DECLARE_READ8_MEMBER(ppi_portb_r);
+ DECLARE_WRITE8_MEMBER(ppi_portb_w);
+ DECLARE_READ8_MEMBER(ppi_portc_r);
+ DECLARE_WRITE8_MEMBER(ppi_portc_w);
+};
+
+void vcc_state::machine_start()
+{
+ fidelbase_state::machine_start();
+
+ // game relies on RAM initialized filled with 1
+ for (int i = 0; i < 0x400; i++)
+ m_maincpu->space(AS_PROGRAM).write_byte(i + 0x4000, 0xff);
+}
+
+
+/******************************************************************************
+ Devices, I/O
+******************************************************************************/
+
+// misc handlers
+
+void vcc_state::prepare_display()
+{
+ // 4 7seg leds (note: sel d0 for extra leds)
+ u8 outdata = (m_7seg_data & 0x7f) | (m_led_select << 7 & 0x80);
+ set_display_segmask(0xf, 0x7f);
+ display_matrix(8, 4, outdata, m_led_select >> 2 & 0xf);
+}
+
+READ8_MEMBER(vcc_state::speech_r)
+{
+ return m_speech_rom[m_speech_bank << 12 | offset];
+}
+
+
+// I8255 PPI
+
+WRITE8_MEMBER(vcc_state::ppi_porta_w)
+{
+ // d0-d6: digit segment data, bits are xABCDEFG
+ m_7seg_data = bitswap<8>(data,7,0,1,2,3,4,5,6);
+ prepare_display();
+
+ // d0-d5: TSI C0-C5
+ // d7: TSI START line
+ m_speech->data_w(space, 0, data & 0x3f);
+ m_speech->start_w(data >> 7 & 1);
+
+ // d6: language latch data
+ // d7: language latch clock (latch on high)
+ if (data & 0x80)
+ {
+ m_speech->force_update(); // update stream to now
+ m_speech_bank = data >> 6 & 1;
+ }
+}
+
+READ8_MEMBER(vcc_state::ppi_portb_r)
+{
+ // d7: TSI BUSY line
+ return (m_speech->busy_r()) ? 0x80 : 0x00;
+}
+
+WRITE8_MEMBER(vcc_state::ppi_portb_w)
+{
+ // d0,d2-d5: digit/led select
+ // _d6: enable language switches
+ m_led_select = data;
+ prepare_display();
+}
+
+READ8_MEMBER(vcc_state::ppi_portc_r)
+{
+ // d0-d3: multiplexed inputs (active low)
+ // also language switches, hardwired with 4 jumpers
+ // 0(none wired): English, 1: German, 2: French, 4: Spanish, 8:Special(unused)
+ u8 lan = (~m_led_select & 0x40) ? m_language : 0;
+ return ~(lan | read_inputs(4)) & 0xf;
+}
+
+WRITE8_MEMBER(vcc_state::ppi_portc_w)
+{
+ // d4-d7: input mux (inverted)
+ m_inp_mux = ~data >> 4 & 0xf;
+}
+
+
+
+/******************************************************************************
+ Address Maps
+******************************************************************************/
+
+void vcc_state::main_map(address_map &map)
+{
+ map.unmap_value_high();
+ map(0x0000, 0x2fff).rom();
+ map(0x4000, 0x43ff).mirror(0x1c00).ram();
+}
+
+void vcc_state::main_io(address_map &map)
+{
+ map.global_mask(0x03);
+ map(0x00, 0x03).rw(m_ppi8255, FUNC(i8255_device::read), FUNC(i8255_device::write));
+}
+
+
+
+/******************************************************************************
+ Input Ports
+******************************************************************************/
+
+static INPUT_PORTS_START( vcc )
+ PORT_START("IN.0")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("LV") PORT_CODE(KEYCODE_L)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("A1") PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_A)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("E5") PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CODE(KEYCODE_E)
+
+ PORT_START("IN.1")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Speaker") PORT_CODE(KEYCODE_SPACE)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("DM") PORT_CODE(KEYCODE_M)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("B2") PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_B)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("F6") PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_F)
+
+ PORT_START("IN.2")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("CL") PORT_CODE(KEYCODE_DEL)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("PB") PORT_CODE(KEYCODE_P)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("C3") PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_C)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("G7") PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_G)
+
+ PORT_START("IN.3")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("EN") PORT_CODE(KEYCODE_ENTER)
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("PV") PORT_CODE(KEYCODE_V)
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("D4") PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_D)
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("H8") PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_H)
+
+ PORT_START("RESET") // is not on matrix IN.0 d0
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("RE") PORT_CODE(KEYCODE_R) PORT_CHANGED_MEMBER(DEVICE_SELF, vcc_state, reset_button, nullptr)
+INPUT_PORTS_END
+
+
+
+/******************************************************************************
+ Machine Drivers
+******************************************************************************/
+
+void vcc_state::vcc(machine_config &config)
+{
+ /* basic machine hardware */
+ Z80(config, m_maincpu, 4_MHz_XTAL);
+ m_maincpu->set_addrmap(AS_PROGRAM, &vcc_state::main_map);
+ m_maincpu->set_addrmap(AS_IO, &vcc_state::main_io);
+
+ I8255(config, m_ppi8255);
+ m_ppi8255->out_pa_callback().set(FUNC(vcc_state::ppi_porta_w));
+ m_ppi8255->tri_pa_callback().set_constant(0);
+ m_ppi8255->in_pb_callback().set(FUNC(vcc_state::ppi_portb_r));
+ m_ppi8255->out_pb_callback().set(FUNC(vcc_state::ppi_portb_w));
+ m_ppi8255->tri_pb_callback().set_constant(0);
+ m_ppi8255->in_pc_callback().set(FUNC(vcc_state::ppi_portc_r));
+ m_ppi8255->out_pc_callback().set(FUNC(vcc_state::ppi_portc_w));
+
+ TIMER(config, "display_decay").configure_periodic(FUNC(fidelbase_state::display_decay_tick), attotime::from_msec(1));
+ config.set_default_layout(layout_fidel_vcc);
+
+ /* sound hardware */
+ SPEAKER(config, "speaker").front_center();
+ S14001A(config, m_speech, 25000); // R/C circuit, around 25khz
+ m_speech->ext_read().set(FUNC(vcc_state::speech_r));
+ m_speech->add_route(ALL_OUTPUTS, "speaker", 0.75);
+}
+
+
+
+/******************************************************************************
+ ROM Definitions
+******************************************************************************/
+
+ROM_START( vcc )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("cn19256n_101-32013", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) )
+ ROM_LOAD("cn19174n_vcc2", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) )
+ ROM_LOAD("cn19175n_vcc3", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-32107", 0x0000, 0x1000, CRC(f35784f9) SHA1(348e54a7fa1e8091f89ac656b4da22f28ca2e44d) )
+ ROM_RELOAD( 0x1000, 0x1000)
+ROM_END
+
+ROM_START( vccg )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("cn19256n_101-32013", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) )
+ ROM_LOAD("cn19174n_vcc2", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) )
+ ROM_LOAD("cn19175n_vcc3", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-64101", 0x0000, 0x2000, BAD_DUMP CRC(6c85e310) SHA1(20d1d6543c1e6a1f04184a2df2a468f33faec3ff) ) // taken from fexcelv, assume correct
+ROM_END
+
+ROM_START( vccsp )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("cn19256n_101-32013", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) )
+ ROM_LOAD("cn19174n_vcc2", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) )
+ ROM_LOAD("cn19175n_vcc3", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-64106", 0x0000, 0x2000, CRC(8766e128) SHA1(78c7413bf240159720b131ab70bfbdf4e86eb1e9) ) // dumped from Spanish VCC, is same as data in fexcelv
+ROM_END
+
+ROM_START( vccfr )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("cn19256n_101-32013", 0x0000, 0x1000, CRC(257bb5ab) SHA1(f7589225bb8e5f3eac55f23e2bd526be780b38b5) )
+ ROM_LOAD("cn19174n_vcc2", 0x1000, 0x1000, CRC(f33095e7) SHA1(692fcab1b88c910b74d04fe4d0660367aee3f4f0) )
+ ROM_LOAD("cn19175n_vcc3", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-64105", 0x0000, 0x2000, BAD_DUMP CRC(fe8c5c18) SHA1(2b64279ab3747ee81c86963c13e78321c6cfa3a3) ) // taken from fexcelv, assume correct
+ROM_END
+
+ROM_START( uvc )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("101-64017", 0x0000, 0x2000, CRC(f1133abf) SHA1(09dd85051c4e7d364d43507c1cfea5c2d08d37f4) ) // MOS // 101-64017 // 3880
+ ROM_LOAD("101-32010", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) ) // NEC P9Z021 // D2332C 228 // 101-32010, == cn19175n_vcc3 on vcc
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-32107", 0x0000, 0x1000, CRC(f35784f9) SHA1(348e54a7fa1e8091f89ac656b4da22f28ca2e44d) ) // NEC P9Y019 // D2332C 229 // 101-32107
+ ROM_RELOAD( 0x1000, 0x1000)
+ROM_END
+
+ROM_START( uvcg )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("101-64017", 0x0000, 0x2000, CRC(f1133abf) SHA1(09dd85051c4e7d364d43507c1cfea5c2d08d37f4) )
+ ROM_LOAD("101-32010", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-64101", 0x0000, 0x2000, BAD_DUMP CRC(6c85e310) SHA1(20d1d6543c1e6a1f04184a2df2a468f33faec3ff) ) // taken from fexcelv, assume correct
+ROM_END
+
+ROM_START( uvcsp )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("101-64017", 0x0000, 0x2000, CRC(f1133abf) SHA1(09dd85051c4e7d364d43507c1cfea5c2d08d37f4) )
+ ROM_LOAD("101-32010", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-64106", 0x0000, 0x2000, CRC(8766e128) SHA1(78c7413bf240159720b131ab70bfbdf4e86eb1e9) )
+ROM_END
+
+ROM_START( uvcfr )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD("101-64017", 0x0000, 0x2000, CRC(f1133abf) SHA1(09dd85051c4e7d364d43507c1cfea5c2d08d37f4) )
+ ROM_LOAD("101-32010", 0x2000, 0x1000, CRC(624f0cd5) SHA1(7c1a4f4497fe5882904de1d6fecf510c07ee6fc6) )
+
+ ROM_REGION( 0x2000, "speech", 0 )
+ ROM_LOAD("101-64105", 0x0000, 0x2000, BAD_DUMP CRC(fe8c5c18) SHA1(2b64279ab3747ee81c86963c13e78321c6cfa3a3) ) // taken from fexcelv, assume correct
+ROM_END
+
+} // anonymous namespace
+
+
+
+/******************************************************************************
+ Drivers
+******************************************************************************/
+
+// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS
+CONS( 1979, vcc, 0, 0, vcc, vcc, vcc_state, init_language<0>, "Fidelity Electronics", "Voice Chess Challenger (English)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1979, vccg, vcc, 0, vcc, vcc, vcc_state, init_language<1>, "Fidelity Electronics", "Voice Chess Challenger (German)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1979, vccsp, vcc, 0, vcc, vcc, vcc_state, init_language<2>, "Fidelity Electronics", "Voice Chess Challenger (Spanish)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1979, vccfr, vcc, 0, vcc, vcc, vcc_state, init_language<4>, "Fidelity Electronics", "Voice Chess Challenger (French)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1980, uvc, vcc, 0, vcc, vcc, vcc_state, init_language<0>, "Fidelity Electronics", "Advanced Voice Chess Challenger (English)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1980, uvcg, vcc, 0, vcc, vcc, vcc_state, init_language<1>, "Fidelity Electronics", "Advanced Voice Chess Challenger (German)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1980, uvcsp, vcc, 0, vcc, vcc, vcc_state, init_language<2>, "Fidelity Electronics", "Advanced Voice Chess Challenger (Spanish)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1980, uvcfr, vcc, 0, vcc, vcc, vcc_state, init_language<4>, "Fidelity Electronics", "Advanced Voice Chess Challenger (French)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )