summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/fidelity/msc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/fidelity/msc.cpp')
-rw-r--r--src/mame/fidelity/msc.cpp237
1 files changed, 237 insertions, 0 deletions
diff --git a/src/mame/fidelity/msc.cpp b/src/mame/fidelity/msc.cpp
new file mode 100644
index 00000000000..407afbfe2d4
--- /dev/null
+++ b/src/mame/fidelity/msc.cpp
@@ -0,0 +1,237 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+// thanks-to:Sean Riddle
+/******************************************************************************
+
+Fidelity Mini Sensory Chess Challenger (model MSC, 1981 version)
+
+Two versions exist, both of them are model MSC. The 1981 version has a Z8 MCU,
+the 1982 version has an I8049. They can also be distinguished from the button
+panel design, the 2nd version has rectangular buttons. See sc6.cpp for the
+2nd version.
+
+Hardware notes:
+- Zilog Z8 MCU(custom label, probably Z8601), 8MHz XTAL
+- buzzer, 18 leds, 8*8 chessboard buttons, module slot
+
+released modules, * denotes not dumped yet:
+- CAC: Challenger Advanced Chess
+- CBO: Challenger Book Openings
+- *CGG: Challenger Greatest Games
+
+As noted in the hash file: The modules have 2 programs in them, one for Z8
+and one for MCS48. A12 is forced high or low to select the bank.
+
+******************************************************************************/
+
+#include "emu.h"
+
+#include "cpu/z8/z8.h"
+#include "machine/sensorboard.h"
+#include "sound/dac.h"
+#include "video/pwm.h"
+#include "bus/generic/slot.h"
+#include "bus/generic/carts.h"
+
+#include "softlist_dev.h"
+#include "speaker.h"
+
+// internal artwork
+#include "fidel_msc_v1.lh" // clickable
+
+
+namespace {
+
+class msc_state : public driver_device
+{
+public:
+ msc_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_board(*this, "board"),
+ m_display(*this, "display"),
+ m_dac(*this, "dac"),
+ m_inputs(*this, "IN.0")
+ { }
+
+ // machine configs
+ void msc(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+
+private:
+ // devices/pointers
+ required_device<z8_device> m_maincpu;
+ required_device<sensorboard_device> m_board;
+ required_device<pwm_display_device> m_display;
+ required_device<dac_bit_interface> m_dac;
+ required_ioport m_inputs;
+
+ // address maps
+ void main_map(address_map &map);
+
+ // I/O handlers
+ void update_display();
+ void mux_w(u8 data);
+ void control_w(u8 data);
+ u8 rom_r(offs_t offset);
+
+ u8 read_inputs();
+ u8 input_hi_r();
+ u8 input_lo_r();
+
+ u8 m_led_select = 0;
+ u16 m_inp_mux = 0;
+};
+
+void msc_state::machine_start()
+{
+ // register for savestates
+ save_item(NAME(m_led_select));
+ save_item(NAME(m_inp_mux));
+}
+
+
+
+/******************************************************************************
+ I/O
+******************************************************************************/
+
+// MCU ports/generic
+
+void msc_state::update_display()
+{
+ m_display->matrix(m_led_select, m_inp_mux);
+}
+
+void msc_state::mux_w(u8 data)
+{
+ // P20-P27: input mux, led data
+ m_inp_mux = (m_inp_mux & 0x100) | data;
+ update_display();
+}
+
+void msc_state::control_w(u8 data)
+{
+ // P37: input mux highest bit
+ // P35,P36: led select
+ m_inp_mux = (m_inp_mux & 0xff) | (data << 1 & 0x100);
+ m_led_select = ~data >> 5 & 3;
+ update_display();
+
+ // P34: speaker out
+ m_dac->write(BIT(~data, 4));
+}
+
+u8 msc_state::read_inputs()
+{
+ u8 data = 0;
+
+ // read chessboard sensors
+ for (int i = 0; i < 8; i++)
+ if (BIT(m_inp_mux, i))
+ data |= m_board->read_file(i);
+
+ // read button panel
+ if (m_inp_mux & 0x100)
+ data |= m_inputs->read();
+
+ return bitswap<8>(~data,0,1,2,3,4,5,6,7);
+}
+
+u8 msc_state::input_hi_r()
+{
+ // P04-P07: multiplexed inputs high
+ return read_inputs() | 0x0f;
+}
+
+u8 msc_state::input_lo_r()
+{
+ // P30-P33: multiplexed inputs low
+ return read_inputs() | 0xf0;
+}
+
+
+
+/******************************************************************************
+ Address Maps
+******************************************************************************/
+
+void msc_state::main_map(address_map &map)
+{
+ map(0x0000, 0x0fff).mirror(0xf000).r("cartslot", FUNC(generic_slot_device::read_rom));
+}
+
+
+
+/******************************************************************************
+ Input Ports
+******************************************************************************/
+
+static INPUT_PORTS_START( msc )
+ PORT_START("IN.0")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("RV / Pawn")
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("DM / Knight")
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Speaker / Bishop")
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("LV / Rook")
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("PV / Queen")
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("PB / King")
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CL")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_NAME("RE")
+INPUT_PORTS_END
+
+
+
+/******************************************************************************
+ Machine Configs
+******************************************************************************/
+
+void msc_state::msc(machine_config &config)
+{
+ /* basic machine hardware */
+ Z8601(config, m_maincpu, 8_MHz_XTAL);
+ m_maincpu->set_addrmap(AS_PROGRAM, &msc_state::main_map);
+ m_maincpu->p0_in_cb().set(FUNC(msc_state::input_hi_r));
+ m_maincpu->p2_out_cb().set(FUNC(msc_state::mux_w));
+ m_maincpu->p3_in_cb().set(FUNC(msc_state::input_lo_r));
+ m_maincpu->p3_out_cb().set(FUNC(msc_state::control_w));
+
+ SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
+ m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
+ m_board->set_delay(attotime::from_msec(150));
+
+ /* video hardware */
+ PWM_DISPLAY(config, m_display).set_size(2, 9);
+ config.set_default_layout(layout_fidel_msc_v1);
+
+ /* sound hardware */
+ SPEAKER(config, "speaker").front_center();
+ DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
+
+ /* cartridge */
+ GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "fidel_msc");
+ SOFTWARE_LIST(config, "cart_list").set_original("fidel_msc");
+}
+
+
+
+/******************************************************************************
+ ROM Definitions
+******************************************************************************/
+
+ROM_START( miniscco )
+ ROM_REGION( 0x0800, "maincpu", 0 )
+ ROM_LOAD("sr0016_1001011a01", 0x0000, 0x0800, CRC(c8cd9bf1) SHA1(4ba165555b8419b03b2ef355da0ed9675315e18b) ) // internal ROM
+ROM_END
+
+} // anonymous namespace
+
+
+
+/******************************************************************************
+ Drivers
+******************************************************************************/
+
+// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
+CONS( 1981, miniscco, miniscc, 0, msc, msc, msc_state, empty_init, "Fidelity Electronics", "Mini Sensory Chess Challenger (1981 version)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )