From 8b018d198c8d6986e3f988ad087c87e080a08868 Mon Sep 17 00:00:00 2001 From: hap Date: Mon, 15 Apr 2019 00:56:46 +0200 Subject: [PATCH] New working machine added --------- Great Game Machine [hap, bataais] --- hash/arb.xml | 18 +- hash/fidel_scc.xml | 6 +- hash/ggm.xml | 22 ++ hash/lantutor.xml | 40 +-- scripts/target/mame/mess.lua | 1 + src/devices/cpu/z80/z80.cpp | 7 +- src/emu/ioport.cpp | 2 +- src/mame/drivers/aci_boris.cpp | 17 +- src/mame/drivers/aci_borisdpl.cpp | 2 +- src/mame/drivers/aci_ggm.cpp | 412 ++++++++++++++++++++++++++++++ src/mame/drivers/ave_arb.cpp | 5 +- src/mame/drivers/fidel_cc1.cpp | 16 +- src/mame/drivers/intellect02.cpp | 4 +- src/mame/drivers/mk1.cpp | 63 +++-- src/mame/layout/aci_ggm.lay | 294 +++++++++++++++++++++ src/mame/layout/cncchess.lay | 10 +- src/mame/layout/snread.lay | 2 - src/mame/layout/snspell.lay | 48 +--- src/mame/layout/snspellsp.lay | 2 - src/mame/layout/spellb.lay | 51 +--- src/mame/mame.lst | 3 + src/mame/mess.flt | 1 + 22 files changed, 878 insertions(+), 148 deletions(-) create mode 100644 hash/ggm.xml create mode 100644 src/mame/drivers/aci_ggm.cpp create mode 100644 src/mame/layout/aci_ggm.lay diff --git a/hash/arb.xml b/hash/arb.xml index 591e97ad15a..e3d303cdd87 100644 --- a/hash/arb.xml +++ b/hash/arb.xml @@ -3,7 +3,7 @@ - + Sargon 2.5 @@ -11,10 +11,10 @@ AVE Micro Systems - - - - + + + + @@ -26,10 +26,10 @@ - - - - + + + + diff --git a/hash/fidel_scc.xml b/hash/fidel_scc.xml index 26f8155a46e..69f0807d57e 100644 --- a/hash/fidel_scc.xml +++ b/hash/fidel_scc.xml @@ -11,7 +11,7 @@ Fidelity Electronics - + @@ -22,8 +22,8 @@ Fidelity Electronics - - + + diff --git a/hash/ggm.xml b/hash/ggm.xml new file mode 100644 index 00000000000..eddd1aa0432 --- /dev/null +++ b/hash/ggm.xml @@ -0,0 +1,22 @@ + + + + + + + + + Boris 2.5 / Sargon 2.5 + 1980 + Applied Concepts + + + + + + + + + + + diff --git a/hash/lantutor.xml b/hash/lantutor.xml index 46710493b2b..859a67f9b66 100644 --- a/hash/lantutor.xml +++ b/hash/lantutor.xml @@ -10,10 +10,10 @@ Texas Instruments - - - - + + + + @@ -24,10 +24,10 @@ Texas Instruments - - - - + + + + @@ -38,10 +38,10 @@ Texas Instruments - - - - + + + + @@ -52,10 +52,10 @@ Texas Instruments - - - - + + + + @@ -66,10 +66,10 @@ Texas Instruments - - - - + + + + diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index c5beded26ca..43e756cd296 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3783,6 +3783,7 @@ files { MAME_DIR .. "src/mame/drivers/aceex.cpp", MAME_DIR .. "src/mame/drivers/aci_boris.cpp", MAME_DIR .. "src/mame/drivers/aci_borisdpl.cpp", + MAME_DIR .. "src/mame/drivers/aci_ggm.cpp", MAME_DIR .. "src/mame/drivers/adm23.cpp", MAME_DIR .. "src/mame/drivers/adm31.cpp", MAME_DIR .. "src/mame/drivers/adm36.cpp", diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index 3454f6773e3..8e1e29a8a1f 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -2,7 +2,7 @@ // copyright-holders:Juergen Buchmueller /***************************************************************************** * - * z80.c + * z80.cpp * Portable Z80 emulator V3.9 * * TODO: @@ -17,8 +17,9 @@ * - OUT (C),0 outputs 0 on NMOS Z80, $FF on CMOS Z80 * - SCF/CCF X/Y flags is ((flags | A) & 0x28) on SGS/SHARP/ZiLOG NMOS Z80, * (flags & A & 0x28) on NEC NMOS Z80, other models unknown. - * However, people from the Speccy scene mention that SCF/CCF X/Y results - * are inconsistant and may be influenced by I and R registers. + * However, recent findings say that SCF/CCF X/Y results depend on whether + * or not the previous instruction touched the flag register. And the exact + * behaviour on NEC Z80 is still unknown. * This Z80 emulator assumes a ZiLOG NMOS model. * * Changes in 3.9: diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index a589abe982e..b2208523b0c 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -1457,7 +1457,7 @@ ioport_field *ioport_port::field(ioport_value mask) const { // if we got the port, look for the field for (ioport_field &field : fields()) - if ((field.mask() & mask) != 0) + if ((field.mask() & mask) != 0 && field.enabled()) return &field; return nullptr; } diff --git a/src/mame/drivers/aci_boris.cpp b/src/mame/drivers/aci_boris.cpp index 457a9807166..c369acc4787 100644 --- a/src/mame/drivers/aci_boris.cpp +++ b/src/mame/drivers/aci_boris.cpp @@ -44,10 +44,11 @@ public: void boris(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER(reset_switch); + DECLARE_INPUT_CHANGED_MEMBER(reset_switch) { update_reset(newval); } protected: virtual void machine_start() override; + virtual void machine_reset() override; private: // devices/pointers @@ -59,6 +60,7 @@ private: void main_map(address_map &map); void main_io(address_map &map); + void update_reset(ioport_value state); TIMER_DEVICE_CALLBACK_MEMBER(delay_display); DECLARE_WRITE8_MEMBER(mux_w); @@ -85,13 +87,18 @@ void boris_state::machine_start() save_item(NAME(m_4042)); } -INPUT_CHANGED_MEMBER(boris_state::reset_switch) +void boris_state::machine_reset() +{ + update_reset(ioport("RESET")->read()); +} + +void boris_state::update_reset(ioport_value state) { // reset switch is tied to MK3850 RESET pin - m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE); // clear display - if (newval) + if (state) { for (int i = 0; i < 8; i++) m_delay_display[i]->adjust(attotime::zero, i); @@ -211,7 +218,7 @@ static INPUT_PORTS_START( boris ) PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") PORT_START("RESET") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_R) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, boris_state, reset_switch, nullptr) PORT_NAME("Reset Switch") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, boris_state, reset_switch, nullptr) PORT_NAME("Reset Switch") INPUT_PORTS_END diff --git a/src/mame/drivers/aci_borisdpl.cpp b/src/mame/drivers/aci_borisdpl.cpp index d2210d63df8..d54104c1097 100644 --- a/src/mame/drivers/aci_borisdpl.cpp +++ b/src/mame/drivers/aci_borisdpl.cpp @@ -181,7 +181,7 @@ static INPUT_PORTS_START( borisdpl ) PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CE") // clear entry PORT_START("RESET") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_CHANGED_MEMBER(DEVICE_SELF, borisdpl_state, reset_button, nullptr) PORT_NAME("Reset") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, borisdpl_state, reset_button, nullptr) PORT_NAME("Reset") INPUT_PORTS_END diff --git a/src/mame/drivers/aci_ggm.cpp b/src/mame/drivers/aci_ggm.cpp new file mode 100644 index 00000000000..bd24f9ad525 --- /dev/null +++ b/src/mame/drivers/aci_ggm.cpp @@ -0,0 +1,412 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/****************************************************************************** + +Applied Concepts Great Game Machine (GGM), electronic board game computer. +2nd source distribution: Modular Game System (MGS), by Chafitz. + +TODO: +- what's VIA PB0 for? game toggles it once per irq +- identify XTAL (2MHz CPU/VIA is correct, compared to video reference) +- add display DP segment (unused in boris25), and what about AP segment? +- verify cartridge pinout, right now assume A0-A14 (max known cart size is 24KB) +- auto-switch keypad overlays? no need for it yet + +******************************************************************************* + +Hardware notes: +- 6502A 2MHz (unknown XTAL, label "5-80"), SYP6522 VIA +- 2KB RAM(4*HM472114AP-2), no ROM on main PCB +- 2*74164 shift register, 3*6118P VFD driver +- 8-digit 14seg VFD panel (same one as in Speak & Spell) +- 5*4 keypad(unlabeled by default), 1-bit sound + +Games are on separate cartridges, each came with a keypad overlay. +There were also some standalone machines, eg. Morphy Encore, Odin Encore. + +Known chess cartridges (*denotes not dumped): +- Chess/Boris 2.5 (aka Sargon 2.5) +- *Gruenfeld Edition - Master Chess Openings +- *Morphy Edition - Master Chess (aka Sandy Edition?) +- *Capablanca Edition - Master Chess Endgame +- *Steinitz Edition-4 - Master Chess +- *Monitor Edition - Master Kriegspiel + +The opening/endgame cartridges are meant to be ejected/inserted while +playing (put the power switch in "MEM" first). + +Other games: +- *Borchek Edition - Master Checkers +- *Odin Edition - Master Reversi +- *Las Vegas 21 +- *Wits End (unreleased?) +- *Lunar Lander (unreleased?) + +******************************************************************************/ + +#include "emu.h" +#include "cpu/m6502/m6502.h" +#include "machine/6522via.h" +#include "machine/nvram.h" +#include "machine/timer.h" +#include "sound/dac.h" +#include "sound/volt_reg.h" +#include "speaker.h" +#include "bus/generic/slot.h" +#include "bus/generic/carts.h" +#include "softlist.h" + +// internal artwork +#include "aci_ggm.lh" // clickable + + +namespace { + +class ggm_state : public driver_device +{ +public: + ggm_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_via(*this, "via"), + m_dac(*this, "dac"), + m_cart(*this, "cartslot"), + m_ca1_off(*this, "ca1_off"), + m_delay_update(*this, "delay_update"), + m_inp_matrix(*this, "IN.%u", 0), + m_out_digit(*this, "digit%u", 0U) + { } + + void ggm(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(reset_switch) { update_reset(newval); } + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + // devices/pointers + required_device m_maincpu; + required_device m_via; + required_device m_dac; + required_device m_cart; + required_device m_ca1_off; + required_device m_delay_update; + required_ioport_array<6> m_inp_matrix; + output_finder<8> m_out_digit; + + void main_map(address_map &map); + + void update_reset(ioport_value state); + void update_display(); + TIMER_DEVICE_CALLBACK_MEMBER(delay_update) { update_display(); } + TIMER_DEVICE_CALLBACK_MEMBER(ca1_off) { m_via->write_ca1(0); } + + u8 m_digit_select; + u16 m_digit_data; + u8 m_shift_data; + u8 m_shift_clock; + u32 m_cart_mask; + + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cartridge); + DECLARE_READ8_MEMBER(cartridge_r); + + DECLARE_WRITE8_MEMBER(select_w); + DECLARE_WRITE8_MEMBER(control_w); + DECLARE_READ8_MEMBER(input_r); + + DECLARE_WRITE_LINE_MEMBER(shift_clock_w); + DECLARE_WRITE_LINE_MEMBER(shift_data_w); +}; + +void ggm_state::machine_start() +{ + // resolve handlers + m_out_digit.resolve(); + + // zerofill + m_digit_select = 0; + m_digit_data = 0; + m_shift_data = 0; + m_shift_clock = 0; + + // register for savestates + save_item(NAME(m_digit_select)); + save_item(NAME(m_digit_data)); + save_item(NAME(m_shift_data)); + save_item(NAME(m_shift_clock)); +} + +void ggm_state::machine_reset() +{ + // it determines whether it's a cold boot or warm boot ("MEM" switch), with CA1 + if (~m_inp_matrix[4]->read() & 2) + { + m_via->write_ca1(1); + m_ca1_off->adjust(attotime::from_msec(10)); + } + else + update_reset(1); +} + +void ggm_state::update_reset(ioport_value state) +{ + // assume that the MEM switch puts the system in reset state (just like Boris) + m_maincpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE); + + if (state) + { + m_via->reset(); + + // clear display + m_digit_data = 0; + m_digit_select = 0xff; + update_display(); + m_digit_select = 0; + } +} + + + +/****************************************************************************** + Devices, I/O +******************************************************************************/ + +// cartridge + +DEVICE_IMAGE_LOAD_MEMBER(ggm_state, cartridge) +{ + u32 size = m_cart->common_get_size("rom"); + m_cart_mask = ((1 << (31 - count_leading_zeros(size))) - 1) & 0x7fff; + + m_cart->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom"); + + return image_init_result::PASS; +} + +READ8_MEMBER(ggm_state::cartridge_r) +{ + return m_cart->read_rom(offset & m_cart_mask); +} + + +// 6522 ports + +void ggm_state::update_display() +{ + u16 data = bitswap<16>(m_digit_data,15,7,2,11,10,3,1,9,6,14,12,5,0,4,13,8); + + for (int i = 0; i < 8; i++) + if (BIT(m_digit_select, i)) + m_out_digit[i] = data & 0x3fff; +} + +WRITE_LINE_MEMBER(ggm_state::shift_clock_w) +{ + // shift display segment data on rising edge + if (state && !m_shift_clock) + m_digit_data = m_digit_data << 1 | (m_shift_data & 1); + + m_shift_clock = state; +} + +WRITE_LINE_MEMBER(ggm_state::shift_data_w) +{ + m_shift_data = state; +} + +WRITE8_MEMBER(ggm_state::select_w) +{ + // update display on rising edge, but delay a bit until shifter is ready + if (~m_digit_select & data && !m_delay_update->enabled()) + m_delay_update->adjust(attotime::from_usec(50)); + + // input mux, digit select + m_digit_select = data; +} + +WRITE8_MEMBER(ggm_state::control_w) +{ + // PB0: ? + + // PB7: speaker out + m_dac->write(BIT(data, 7)); + +} + +READ8_MEMBER(ggm_state::input_r) +{ + u16 data = 0; + + // PB1-PB5: multiplexed inputs + for (int i = 0; i < 4; i++) + if (BIT(m_digit_select, i)) + data |= m_inp_matrix[i]->read(); + + data |= data >> 8; + data = ~data << 1 & 0x3e; + + + // PB6: hardware version + return 0x81 | data | (m_inp_matrix[4]->read() << 6 & 0x40); +} + + + +/****************************************************************************** + Address Maps +******************************************************************************/ + +void ggm_state::main_map(address_map &map) +{ + // external slot has potential bus conflict with RAM/VIA + map(0x0000, 0x7fff).mirror(0x8000).r(FUNC(ggm_state::cartridge_r)); + map(0x0000, 0x07ff).ram().share("nvram"); + map(0x8000, 0x800f).rw(m_via, FUNC(via6522_device::read), FUNC(via6522_device::write)); +} + + + +/****************************************************************************** + Input Ports +******************************************************************************/ + +#define OVERLAY(val) \ + PORT_CONDITION("IN.5", 0x01, EQUALS, val) + +static INPUT_PORTS_START( overlay_boris ) // actually most of the Chess games have a similar overlay + PORT_MODIFY("IN.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_A) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("A.1 / Pawn") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_B) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("B.2 / Knight") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("C.3 / Bishop") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_D) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("D.4 / Rook") + + PORT_MODIFY("IN.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_E) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("E.5 / Queen") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_F) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("F.6 / King") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_G) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("G.7") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("H.8") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9") + + PORT_MODIFY("IN.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_SPACE) PORT_CODE(KEYCODE_MINUS) PORT_NAME("-") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_W) PORT_NAME("B/W") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_K) PORT_NAME("Rank") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_T) PORT_NAME("Time") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_DEL) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("CE") + + PORT_MODIFY("IN.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_L) PORT_NAME("Level") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_H) PORT_NAME("Halt / Hint") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_S) PORT_NAME("Best") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_R) PORT_NAME("Restore") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x01) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter") +INPUT_PORTS_END + +static INPUT_PORTS_START( ggm ) + PORT_START("IN.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_X) PORT_NAME("Keypad 4-2") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_S) PORT_NAME("Keypad 3-2") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_D) PORT_NAME("Keypad 3-3") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_F) PORT_NAME("Keypad 3-4") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_W) PORT_NAME("Keypad 2-2") + + PORT_START("IN.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_E) PORT_NAME("Keypad 2-3") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_R) PORT_NAME("Keypad 2-4") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_2) PORT_NAME("Keypad 1-2") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_3) PORT_NAME("Keypad 1-3") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_4) PORT_NAME("Keypad 1-4") + + PORT_START("IN.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_C) PORT_NAME("Keypad 4-3") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_V) PORT_NAME("Keypad 4-4") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_G) PORT_NAME("Keypad 3-5") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_T) PORT_NAME("Keypad 2-5") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_5) PORT_NAME("Keypad 1-5") + + PORT_START("IN.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_Z) PORT_NAME("Keypad 4-1") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_Q) PORT_NAME("Keypad 2-1") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_A) PORT_NAME("Keypad 3-1") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_1) PORT_NAME("Keypad 1-1") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) OVERLAY(0x00) PORT_CODE(KEYCODE_B) PORT_NAME("Keypad 4-5") + + PORT_INCLUDE( overlay_boris ) + + PORT_START("IN.4") + PORT_CONFNAME( 0x01, 0x00, "Version" ) // factory-set + PORT_CONFSETTING( 0x00, "GGS (Applied Concepts)" ) + PORT_CONFSETTING( 0x01, "MGS (Chafitz)" ) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, ggm_state, reset_switch, nullptr) PORT_NAME("Memory Switch") + + PORT_START("IN.5") + PORT_CONFNAME( 0x01, 0x01, "Keypad Overlay" ) + PORT_CONFSETTING( 0x00, "None" ) + PORT_CONFSETTING( 0x01, "Boris 2.5" ) +INPUT_PORTS_END + + + +/****************************************************************************** + Machine Configs +******************************************************************************/ + +void ggm_state::ggm(machine_config &config) +{ + /* basic machine hardware */ + M6502(config, m_maincpu, 2000000); + m_maincpu->set_addrmap(AS_PROGRAM, &ggm_state::main_map); + + VIA6522(config, m_via, 2000000); // DDRA = 0xff, DDRB = 0x81 + m_via->writepa_handler().set(FUNC(ggm_state::select_w)); + m_via->writepb_handler().set(FUNC(ggm_state::control_w)); + m_via->readpb_handler().set(FUNC(ggm_state::input_r)); + m_via->irq_handler().set_inputline(m_maincpu, M6502_IRQ_LINE); + m_via->cb1_handler().set(FUNC(ggm_state::shift_clock_w)); + m_via->cb2_handler().set(FUNC(ggm_state::shift_data_w)); + TIMER(config, m_ca1_off).configure_generic(FUNC(ggm_state::ca1_off)); + + NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); + + /* video hardware */ + TIMER(config, m_delay_update).configure_generic(FUNC(ggm_state::delay_update)); + config.set_default_layout(layout_aci_ggm); + + /* sound hardware */ + SPEAKER(config, "speaker").front_center(); + DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25); + VOLTAGE_REGULATOR(config, "vref").add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT); + + /* cartridge */ + GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "ggm", "bin"); + m_cart->set_device_load(device_image_load_delegate(&ggm_state::device_image_load_cartridge, this)); + m_cart->set_must_be_loaded(true); + + SOFTWARE_LIST(config, "cart_list").set_original("ggm"); +} + + + +/****************************************************************************** + ROM Definitions +******************************************************************************/ + +ROM_START( ggm ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) + // nothing here, ROM is on cartridge +ROM_END + +} // anonymous namespace + + + +/****************************************************************************** + Drivers +******************************************************************************/ + +// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS +COMP( 1980, ggm, 0, 0, ggm, ggm, ggm_state, empty_init, "Applied Concepts", "Great Game Machine", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/drivers/ave_arb.cpp b/src/mame/drivers/ave_arb.cpp index 638c5533549..8e75c684d9a 100644 --- a/src/mame/drivers/ave_arb.cpp +++ b/src/mame/drivers/ave_arb.cpp @@ -23,12 +23,15 @@ The electronic magnetic chessboard is the first of is kind. AVE later licensed it to Fidelity (see fidel_elite.cpp). ARB is a romless system, the program ROM is on a cartridge. -Known modules (*denotes not dumped yet): +Known chess modules (*denotes not dumped yet): - Sargon 2.5 - *Grand Master Series 3 - *Grand Master Series 3.5 - Grand Master Series 4.0 +Other games: +- *Avelan (checkers) + Newer modules included button label stickers for OPTIONS, Verify, Take Back, Clear. Around 2012, Steve Braid(aka Trilobyte/Steve UK) started manufacturing ARB V2 boards diff --git a/src/mame/drivers/fidel_cc1.cpp b/src/mame/drivers/fidel_cc1.cpp index 8bd68cf38b8..53d06cc985e 100644 --- a/src/mame/drivers/fidel_cc1.cpp +++ b/src/mame/drivers/fidel_cc1.cpp @@ -20,11 +20,17 @@ This is the world's 1st released dedicated chess computer. Oddly, the rows/colum are reversed: left to right is 1-8, bottom to top is A-H, eg. pawn from D2 to D4 is 4B to 4D here. -PCB label PC-P-86, P179 C-2 7.77 -NEC 8080AF @ 2MHz(18MHz XTAL through a 8224) -Everything goes via a NEC B8228, its special features are unused. -NEC 2316A ROM(2KB), 4*2101AL RAM(0.5KB total) -8255C for I/O, 4*7seg display + 2 extra leds, 12-key keypad +The CC1 patent(US4235442) refers to a Hewlett Packard chess program. It was eventually +found out that it was written for a HP-9810A by Alan A. Wray in 1974, and CC1 is very +similar to it. Ron C. Nelson must have ported the algorithms to 8080 when he wrote +his Altair 8800 chess program, and this is what made it into CC1. + +CC1 hardware overview: +- PCB label PC-P-86, P179 C-2 7.77 +- NEC 8080AF @ 2MHz(18MHz XTAL through a 8224) +- Everything goes via a NEC B8228, its special features are unused. +- NEC 2316A ROM(2KB), 4*2101AL RAM(0.5KB total) +- 8255C for I/O, 4*7seg display + 2 extra leds, 12-key keypad Chess Challenger 3 is on the same hardware, but with double ROM size, and they corrected the reversed chess notation. It was also offered as an upgrade to CC1. diff --git a/src/mame/drivers/intellect02.cpp b/src/mame/drivers/intellect02.cpp index 019a46b244b..a87a0367b02 100644 --- a/src/mame/drivers/intellect02.cpp +++ b/src/mame/drivers/intellect02.cpp @@ -6,7 +6,7 @@ Интеллект-02 (Intellect-02) driver This is a Soviet electronic board game console, a dozen or so cartridge games were -made for it(can't say for certain how many released). PCB labels have prefix ДМП, +announced(can't say for certain how many released). PCB labels have prefix ДМП, it's assumed to have been designed by НИИ БРЭА (SRI BREA). First shown in 1983, produced during around 1985-1992. @@ -218,7 +218,7 @@ WRITE8_MEMBER(intel02_state::control_w) if (!m_delay_update->enabled()) m_delay_update->adjust(attotime::from_usec(15)); - // d6: N/C + // d6: N/C (it's a delay timer on CC3) // d7: enable beeper m_beeper->set_state(BIT(data, 7)); diff --git a/src/mame/drivers/mk1.cpp b/src/mame/drivers/mk1.cpp index 4fa70565fed..a5650714cc9 100644 --- a/src/mame/drivers/mk1.cpp +++ b/src/mame/drivers/mk1.cpp @@ -7,8 +7,7 @@ Driver file to handle emulation of the Novag/Videomaster Chess Champion MK I Initial version by PeT mess@utanet.at 2000,2001. TODO: -- verify cncchess beeper duration/frequency -- cncchess middle leds +- cncchess sound is wrong, it should be a long dual-tone alarm sound ******************************************************************************* @@ -89,17 +88,20 @@ public: m_beeper(*this, "beeper"), m_keypad(*this, "LINE%u", 1U), m_delay_display(*this, "delay_display_%u", 0), - m_out_digit(*this, "digit%u", 0U) + m_out_digit(*this, "digit%u", 0U), + m_out_led(*this, "led%u", 0U), + m_out_leda(*this, "led%ua", 0U) { } void cmpchess(machine_config &config); void mk1(machine_config &config); void cnc(machine_config &config); - DECLARE_INPUT_CHANGED_MEMBER(reset_switch); + DECLARE_INPUT_CHANGED_MEMBER(reset_switch) { update_reset(newval); } protected: virtual void machine_start() override; + virtual void machine_reset() override; private: // devices/pointers @@ -109,6 +111,8 @@ private: required_ioport_array<4> m_keypad; required_device_array m_delay_display; output_finder<4> m_out_digit; + output_finder<4> m_out_led; + output_finder<4> m_out_leda; void main_map(address_map &map); void main_io(address_map &map); @@ -117,7 +121,9 @@ private: TIMER_DEVICE_CALLBACK_MEMBER(beeper_off) { m_beeper->set_state(0); } TIMER_DEVICE_CALLBACK_MEMBER(blink) { m_blink = !m_blink; update_display(); } TIMER_DEVICE_CALLBACK_MEMBER(delay_display); + void clear_digit(int i); void update_display(); + void update_reset(ioport_value state); DECLARE_READ8_MEMBER(beeper_r); DECLARE_WRITE8_MEMBER(input_w); @@ -139,6 +145,8 @@ void mk1_state::machine_start() { // resolve handlers m_out_digit.resolve(); + m_out_led.resolve(); + m_out_leda.resolve(); // zerofill m_inp_mux = 0; @@ -153,17 +161,30 @@ void mk1_state::machine_start() save_item(NAME(m_blink)); } -INPUT_CHANGED_MEMBER(mk1_state::reset_switch) +void mk1_state::machine_reset() +{ + update_reset(ioport("RESET")->read()); +} + +void mk1_state::clear_digit(int i) +{ + // clear digit + connected leds + m_out_digit[i] = 0; + m_out_led[i] = 0; + m_out_leda[i] = 0; +} + +void mk1_state::update_reset(ioport_value state) { // reset switch is tied to F3850 RESET pin - m_maincpu->set_input_line(INPUT_LINE_RESET, newval ? ASSERT_LINE : CLEAR_LINE); + m_maincpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE); // clear display - if (newval) + if (state) { m_digit_select = 0xff; for (int i = 0; i < 4; i++) - m_out_digit[i] = 0; + clear_digit(i); } } @@ -179,7 +200,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(mk1_state::delay_display) { // clear digits if inactive if (BIT(m_digit_select, param)) - m_out_digit[param] = 0; + clear_digit(param); } void mk1_state::update_display() @@ -189,11 +210,15 @@ void mk1_state::update_display() { if (!BIT(m_digit_select, i)) { - // display panel goes into automated blink mode if DP segment is held high - // and DP segment itself only appears to be active if no other segments are - u8 mask = (m_digit_data == 1) ? 0x80 : 0x7f; - mask = (m_blink && m_digit_data & 1) ? 0 : mask; - m_out_digit[i] = bitswap<8>(m_digit_data,0,2,1,3,4,5,6,7) & mask; + // display panel goes into automated blink mode if DP segment is held high, + // and DP segment itself by default only appears to be active if no other segments are + u8 dmask = (m_digit_data == 1) ? 0x80 : 0x7f; + u8 bmask = (m_blink && m_digit_data & 1) ? 0 : 0xff; + m_out_digit[i] = bitswap<8>(m_digit_data,0,2,1,3,4,5,6,7) & dmask & bmask; + + // output led separately too + m_out_led[i] = (m_out_digit[i] & 0x80) ? 1 : 0; + m_out_leda[i] = m_digit_data & bmask & 1; // for ignoring dmask above } } } @@ -207,7 +232,7 @@ READ8_MEMBER(mk1_state::beeper_r) if (!machine().side_effects_disabled() && m_beeper != nullptr) { m_beeper->set_state(1); - m_beeper_off->adjust(attotime::from_msec(50)); // guessed + m_beeper_off->adjust(attotime::from_msec(50)); // wrong, see TODO } return m_maincpu->space(AS_PROGRAM).read_byte(offset); @@ -318,7 +343,7 @@ static INPUT_PORTS_START( cmpchess ) PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8 / ep") // enter piece(position) PORT_START("RESET") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_R) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, mk1_state, reset_switch, nullptr) PORT_NAME("Reset Switch") // L.S. switch on the MK I + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_CODE(KEYCODE_F1) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, mk1_state, reset_switch, nullptr) PORT_NAME("Reset Switch") // L.S. switch on the MK I INPUT_PORTS_END static INPUT_PORTS_START( cncchess ) @@ -347,7 +372,7 @@ static INPUT_PORTS_START( cncchess ) PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("H / GO") PORT_START("RESET") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) PORT_CHANGED_MEMBER(DEVICE_SELF, mk1_state, reset_switch, nullptr) PORT_NAME("Reset") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, mk1_state, reset_switch, nullptr) PORT_NAME("Reset") INPUT_PORTS_END @@ -397,7 +422,7 @@ void mk1_state::cnc(machine_config &config) /* sound hardware */ SPEAKER(config, "speaker").front_center(); - BEEP(config, m_beeper, 2000); // guessed + BEEP(config, m_beeper, 2000); // wrong, see TODO m_beeper->add_route(ALL_OUTPUTS, "speaker", 0.25); TIMER(config, "beeper_off").configure_generic(FUNC(mk1_state::beeper_off)); } @@ -436,4 +461,4 @@ ROM_END CONS( 1977, cmpchess, 0, 0, cmpchess, cmpchess, mk1_state, empty_init, "Data Cash Systems", "CompuChess", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) CONS( 1978, ccmk1, cmpchess, 0, mk1, cmpchess, mk1_state, empty_init, "Novag", "Chess Champion: MK I", MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) -CONS( 1979, cncchess, 0, 0, cnc, cncchess, mk1_state, empty_init, "Conic", "Computer Chess (Conic)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) +CONS( 1979, cncchess, 0, 0, cnc, cncchess, mk1_state, empty_init, "Conic", "Computer Chess (Conic)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/layout/aci_ggm.lay b/src/mame/layout/aci_ggm.lay new file mode 100644 index 00000000000..7894cc36315 --- /dev/null +++ b/src/mame/layout/aci_ggm.lay @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/layout/cncchess.lay b/src/mame/layout/cncchess.lay index 0546d2e8a0e..432c6146365 100644 --- a/src/mame/layout/cncchess.lay +++ b/src/mame/layout/cncchess.lay @@ -195,8 +195,12 @@ - - + + + + + + @@ -270,7 +274,7 @@ - + diff --git a/src/mame/layout/snread.lay b/src/mame/layout/snread.lay index 23b285b751c..26da6cf2c80 100644 --- a/src/mame/layout/snread.lay +++ b/src/mame/layout/snread.lay @@ -3,8 +3,6 @@ - - diff --git a/src/mame/layout/snspell.lay b/src/mame/layout/snspell.lay index 78a50fea709..752e81ab234 100644 --- a/src/mame/layout/snspell.lay +++ b/src/mame/layout/snspell.lay @@ -3,25 +3,22 @@ - - - + - + - @@ -29,37 +26,18 @@ - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/mame/layout/snspellsp.lay b/src/mame/layout/snspellsp.lay index a13712b7ea1..7e9b48a05e5 100644 --- a/src/mame/layout/snspellsp.lay +++ b/src/mame/layout/snspellsp.lay @@ -3,8 +3,6 @@ - - diff --git a/src/mame/layout/spellb.lay b/src/mame/layout/spellb.lay index 0398108caff..752e81ab234 100644 --- a/src/mame/layout/spellb.lay +++ b/src/mame/layout/spellb.lay @@ -3,21 +3,17 @@ - - - - - + - + @@ -26,41 +22,22 @@ - + - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index d062a8aa3fb..ce99ae93328 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -879,6 +879,9 @@ borisa // @source:aci_borisdpl.cpp borisdpl // +@source:aci_ggm.cpp +ggm + @source:acommand.cpp acommand // (c) 1990 diff --git a/src/mame/mess.flt b/src/mame/mess.flt index c874689ea3f..c4c4621cac5 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -18,6 +18,7 @@ acd.cpp aceex.cpp aci_boris.cpp aci_borisdpl.cpp +aci_ggm.cpp acrnsys1.cpp acrnsys.cpp acvirus.cpp