chessmst: split driver into chessmst/chessmstdm

This commit is contained in:
hap 2021-05-03 23:39:33 +02:00
parent 2cf018ffd2
commit 993e9e69e0
8 changed files with 498 additions and 280 deletions

View File

@ -4222,6 +4222,7 @@ files {
createMESSProjects(_target, _subtarget, "veb")
files {
MAME_DIR .. "src/mame/drivers/chessmst.cpp",
MAME_DIR .. "src/mame/drivers/chessmstdm.cpp",
MAME_DIR .. "src/mame/drivers/kc.cpp",
MAME_DIR .. "src/mame/includes/kc.h",
MAME_DIR .. "src/mame/machine/kc.cpp",

View File

@ -1,39 +1,44 @@
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco
/***************************************************************************
// copyright-holders:Sandro Ronco, hap
/******************************************************************************
Chess-Master (G-5003-500) (10*U505 roms)
Chess-Master (G-5003-501) (2 roms set)
Chess-Master Diamond (G-5004-500)
Unlike SC2, the chess engine was not copied from an existing one. It is an
original creation by Rüdiger Worbs and Dieter Schultze. It competed in
Budapest WMCCC 1983 and ended at a low 16th place.
Hardware notes:
- UB880 Z80 @ ~2.5MHz
- 2*Z80 PIO
- 10KB ROM (10*U505D), 1KB RAM (4*U214D)
- chessboard with 64 hall sensors, 64+15 leds, piezo
A newer version had a 4MHz UA880 and 2 ROM chips (8KB + 2KB).
BTANB:
- chessmst corner leds flicker sometimes
- corner leds flicker sometimes
TODO:
- split driver? much difference between chessmst/chessmstdm
- chessmsta isn't working, needs a redump of u2616. Program differences are
minor so it seems to boot fine if you take 064/065 from chessmst, but will
probably have some problems.
***************************************************************************/
******************************************************************************/
#include "emu.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "cpu/z80/z80.h"
#include "machine/clock.h"
#include "machine/z80pio.h"
#include "machine/sensorboard.h"
#include "sound/beep.h"
#include "sound/spkrdev.h"
#include "sound/dac.h"
#include "video/pwm.h"
#include "speaker.h"
// internal artwork
#include "chessmst.lh"
#include "chessmstdm.lh"
namespace {
@ -47,13 +52,8 @@ public:
m_pio(*this, "z80pio%u", 0),
m_board(*this, "board"),
m_led_pwm(*this, "led_pwm"),
m_digit_pwm(*this, "digit_pwm"),
m_speaker(*this, "speaker"),
m_beeper(*this, "beeper"),
m_extra(*this, "EXTRA"),
m_buttons(*this, "BUTTONS"),
m_digits(*this, "digit%u", 0U),
m_direct_led(*this, "dled%u", 0U)
m_dac(*this, "dac"),
m_inputs(*this, "IN.%u", 0)
{ }
DECLARE_INPUT_CHANGED_MEMBER(halt_button);
@ -61,7 +61,6 @@ public:
void chessmst(machine_config &config);
void chessmsta(machine_config &config);
void chessmstdm(machine_config &config);
protected:
virtual void machine_start() override;
@ -71,53 +70,89 @@ private:
required_device_array<z80pio_device, 2> m_pio;
required_device<sensorboard_device> m_board;
required_device<pwm_display_device> m_led_pwm;
optional_device<pwm_display_device> m_digit_pwm;
optional_device<speaker_sound_device> m_speaker;
optional_device<beep_device> m_beeper;
required_ioport m_extra;
required_ioport m_buttons;
output_finder<4> m_digits;
output_finder<2> m_direct_led;
required_device<dac_bit_interface> m_dac;
required_ioport_array<2> m_inputs;
void chessmst_io(address_map &map);
void chessmst_mem(address_map &map);
void chessmstdm_mem(address_map &map);
void chessmstdm_io(address_map &map);
void digits_w(uint8_t data);
void pio1_port_a_w(uint8_t data);
void pio1_port_b_w(uint8_t data);
void pio1_port_b_dm_w(uint8_t data);
uint8_t pio2_port_a_r();
void pio2_port_b_w(uint8_t data);
DECLARE_WRITE_LINE_MEMBER(timer_555_w);
void pio1_port_a_w(u8 data);
void pio1_port_b_w(u8 data);
u8 pio2_port_a_r();
void pio2_port_b_w(u8 data);
void update_leds();
void update_digits();
uint16_t m_matrix = 0;
uint8_t m_led_data = 0;
uint8_t m_led_data2 = 0;
uint8_t m_digit_matrix = 0;
int m_digit_dot = 0;
uint16_t m_digit_data = 0;
u16 m_matrix = 0;
u8 m_led_data[2] = { 0, 0 };
};
void chessmst_state::machine_start()
{
m_digits.resolve();
m_direct_led.resolve();
// register for savestates
save_item(NAME(m_matrix));
save_item(NAME(m_led_data));
save_item(NAME(m_led_data2));
save_item(NAME(m_digit_matrix));
save_item(NAME(m_digit_dot));
save_item(NAME(m_digit_data));
}
// Address Maps
/******************************************************************************
I/O
******************************************************************************/
void chessmst_state::update_leds()
{
m_led_pwm->matrix(m_matrix, m_led_data[0] | m_led_data[1]);
}
void chessmst_state::pio1_port_a_w(u8 data)
{
// d0-d7: led data
m_led_data[0] = ~data;
update_leds();
}
void chessmst_state::pio1_port_b_w(u8 data)
{
// d0,d1: input mux/led select high
m_matrix = (m_matrix & 0xff) | ((data & 0x03) << 8);
// d2,d3: led data 2nd/3rd rows (duplicate)
m_led_data[1] = ~data >> 1 & 6;
update_leds();
// d6: speaker out
m_dac->write(BIT(data, 6));
}
u8 chessmst_state::pio2_port_a_r()
{
u8 data = 0xff;
// read chessboard sensors
for (int i = 0; i < 8; i++)
if (BIT(m_matrix, i))
data &= ~m_board->read_file(i);
// read other buttons
if (m_matrix & 0x100)
data &= m_inputs[0]->read();
return data;
}
void chessmst_state::pio2_port_b_w(u8 data)
{
// d0-d7: input mux/led select
m_matrix = (data & 0xff) | (m_matrix & ~0xff);
update_leds();
}
/******************************************************************************
Address Maps
******************************************************************************/
void chessmst_state::chessmst_mem(address_map &map)
{
@ -127,160 +162,55 @@ void chessmst_state::chessmst_mem(address_map &map)
map(0x3400, 0x3bff).ram();
}
void chessmst_state::chessmstdm_mem(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x3fff).rom();
map(0x4000, 0x7fff).r("cartslot", FUNC(generic_slot_device::read_rom));
map(0x8000, 0x8bff).ram();
}
void chessmst_state::chessmst_io(address_map &map)
{
map.unmap_value_high();
map.global_mask(0xff);
//map(0x00, 0x03).mirror(0xf0); read/write in both, not used by the software
map(0x04, 0x07).mirror(0xf0).rw(m_pio[0], FUNC(z80pio_device::read), FUNC(z80pio_device::write));
map(0x08, 0x0b).mirror(0xf0).rw(m_pio[1], FUNC(z80pio_device::read), FUNC(z80pio_device::write));
}
void chessmst_state::chessmstdm_io(address_map &map)
{
chessmst_io(map);
map(0x4c, 0x4c).w(FUNC(chessmst_state::digits_w));
}
WRITE_LINE_MEMBER(chessmst_state::timer_555_w)
{
m_pio[1]->strobe_b(state);
m_pio[1]->data_b_write(m_matrix);
map.global_mask(0x0f);
//map(0x00, 0x03) read/write to both PIOs, but not used by software
map(0x04, 0x07).rw(m_pio[0], FUNC(z80pio_device::read), FUNC(z80pio_device::write));
map(0x08, 0x0b).rw(m_pio[1], FUNC(z80pio_device::read), FUNC(z80pio_device::write));
}
// Input ports
/******************************************************************************
Input Ports
******************************************************************************/
INPUT_CHANGED_MEMBER(chessmst_state::halt_button)
{
m_pio[0]->strobe_a(newval);
reset_button(field, param, 0, 0);
reset_button(field, param, oldval, newval);
}
INPUT_CHANGED_MEMBER(chessmst_state::reset_button)
{
// pressing both 'extra' buttons causes a reset
const bool reset = (m_extra->read() & 0x03) == 0x03;
// pressing both halt+reset buttons causes a reset
const bool reset = (m_inputs[1]->read() & 0x03) == 0x03;
m_maincpu->set_input_line(INPUT_LINE_RESET, reset ? ASSERT_LINE : CLEAR_LINE);
}
static INPUT_PORTS_START( chessmst )
PORT_START("BUTTONS")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Hint / 7") PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_H)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Random / 6") PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_R)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Referee / 5") PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CODE(KEYCODE_F)
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Self Play / 4") PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_S)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Board / 3") PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_B)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Color / 2") PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_C)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Level / 1") PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_L)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("New Game / 0") PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_N)
PORT_START("IN.0")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Hint / 7") PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_H)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Random / 6") PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_R)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Referee / 5") PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_CODE(KEYCODE_F)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Self Play / 4") PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_S)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Board / 3") PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_B)
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Color / 2") PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_C)
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Level / 1") PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_L)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("New Game / 0") PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_N)
PORT_START("EXTRA")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Halt") PORT_CODE(KEYCODE_F2) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmst_state, halt_button, 0) // -> PIO(0) ASTB pin
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmst_state, reset_button, 0) // -> Z80 RESET pin if HALT is pressed too
INPUT_PORTS_END
static INPUT_PORTS_START( chessmstdm )
PORT_START("BUTTONS")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Move Fore") PORT_CODE(KEYCODE_RIGHT)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Move Back") PORT_CODE(KEYCODE_LEFT)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Board") PORT_CODE(KEYCODE_B)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Match / Time") PORT_CODE(KEYCODE_M)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Parameter / Information") PORT_CODE(KEYCODE_I)
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Selection / Dialogue") PORT_CODE(KEYCODE_S)
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Function / Notation") PORT_CODE(KEYCODE_F)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD)
PORT_START("EXTRA")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Monitor") PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmst_state, reset_button, 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("View") PORT_CODE(KEYCODE_F2) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmst_state, reset_button, 0)
PORT_START("IN.1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Halt") PORT_CODE(KEYCODE_F2) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmst_state, halt_button, 0) // -> PIO(0) ASTB pin
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmst_state, reset_button, 0) // -> Z80 RESET pin if HALT is pressed too
INPUT_PORTS_END
// I/O
void chessmst_state::update_digits()
{
uint16_t digit_data = bitswap<16>(m_digit_data, 3,5,12,10,14,1,2,13,8,6,11,15,7,9,4,0);
m_digit_pwm->matrix(m_digit_matrix, digit_data | (m_digit_dot << 16));
}
void chessmst_state::digits_w(uint8_t data)
{
m_digit_data = (m_digit_data << 4) | (data & 0x0f);
m_digit_matrix = (data >> 4) & 0x0f;
update_digits();
}
void chessmst_state::update_leds()
{
m_led_pwm->matrix(m_matrix, m_led_data | m_led_data2);
}
void chessmst_state::pio1_port_a_w(uint8_t data)
{
m_led_data = ~data;
update_leds();
}
void chessmst_state::pio1_port_b_w(uint8_t data)
{
m_matrix = (m_matrix & 0xff) | ((data & 0x03)<<8);
m_led_data2 = ~data >> 1 & 6;
update_leds();
m_speaker->level_w(BIT(data, 6));
}
void chessmst_state::pio1_port_b_dm_w(uint8_t data)
{
m_matrix = (m_matrix & 0xff) | ((data & 0x04)<<6);
m_digit_dot = BIT(data, 4);
update_digits();
m_beeper->set_state(BIT(data, 3));
m_direct_led[0] = BIT(data, 5); // monitor
m_direct_led[1] = BIT(data, 6); // playmode
// d4 and d7 also go to cartslot, but unused
}
uint8_t chessmst_state::pio2_port_a_r()
{
uint8_t data = 0;
// The pieces position on the chessboard is identified by 64 Hall
// sensors, which are in a 8x8 matrix with the corresponding LEDs.
for (int i = 0; i < 8; i++)
{
if (BIT(m_matrix, i))
data |= m_board->read_file(i);
}
if (m_matrix & 0x100)
data |= m_buttons->read();
return ~data;
}
void chessmst_state::pio2_port_b_w(uint8_t data)
{
m_matrix = (data & 0xff) | (m_matrix & ~0xff);
update_leds();
}
// Machine Configuration
/******************************************************************************
Machine Configs
******************************************************************************/
static const z80_daisy_config chessmst_daisy_chain[] =
{
@ -288,26 +218,20 @@ static const z80_daisy_config chessmst_daisy_chain[] =
{ nullptr }
};
static const z80_daisy_config chessmstdm_daisy_chain[] =
{
{ "z80pio1" },
{ nullptr }
};
void chessmst_state::chessmst(machine_config &config)
{
// basic machine hardware
Z80(config, m_maincpu, 9.8304_MHz_XTAL/4); // UB880 Z80 clone
Z80(config, m_maincpu, 9.8304_MHz_XTAL / 4);
m_maincpu->set_addrmap(AS_PROGRAM, &chessmst_state::chessmst_mem);
m_maincpu->set_addrmap(AS_IO, &chessmst_state::chessmst_io);
m_maincpu->set_daisy_config(chessmst_daisy_chain);
Z80PIO(config, m_pio[0], 9.8304_MHz_XTAL/4);
Z80PIO(config, m_pio[0], 9.8304_MHz_XTAL / 4);
m_pio[0]->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_pio[0]->out_pa_callback().set(FUNC(chessmst_state::pio1_port_a_w));
m_pio[0]->out_pb_callback().set(FUNC(chessmst_state::pio1_port_b_w));
Z80PIO(config, m_pio[1], 9.8304_MHz_XTAL/4);
Z80PIO(config, m_pio[1], 9.8304_MHz_XTAL / 4);
m_pio[1]->in_pa_callback().set(FUNC(chessmst_state::pio2_port_a_r));
m_pio[1]->out_pb_callback().set(FUNC(chessmst_state::pio2_port_b_w));
@ -321,8 +245,8 @@ void chessmst_state::chessmst(machine_config &config)
config.set_default_layout(layout_chessmst);
// sound hardware
SPEAKER(config, "mono").front_center();
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25);
SPEAKER(config, "speaker").front_center();
DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25);
}
void chessmst_state::chessmsta(machine_config &config)
@ -336,53 +260,24 @@ void chessmst_state::chessmsta(machine_config &config)
m_pio[1]->set_clock(clk);
}
void chessmst_state::chessmstdm(machine_config &config)
{
chessmsta(config);
// basic machine hardware
m_maincpu->set_addrmap(AS_PROGRAM, &chessmst_state::chessmstdm_mem);
m_maincpu->set_addrmap(AS_IO, &chessmst_state::chessmstdm_io);
m_maincpu->set_daisy_config(chessmstdm_daisy_chain);
CLOCK(config, "555_timer", 500).signal_handler().set(FUNC(chessmst_state::timer_555_w));
m_pio[0]->out_pb_callback().set(FUNC(chessmst_state::pio1_port_b_dm_w));
m_pio[0]->in_pb_callback().set_ioport("EXTRA");
m_pio[0]->out_int_callback().set_nop();
m_pio[1]->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
// video hardware
PWM_DISPLAY(config, m_digit_pwm).set_size(4, 17);
m_digit_pwm->set_segmask(0xf, 0x1ffff);
m_digit_pwm->output_digit().set([this](offs_t offset, uint64_t data) { m_digits[offset] = data; });
config.set_default_layout(layout_chessmstdm);
// sound hardware
config.device_remove("speaker");
BEEP(config, m_beeper, 1000).add_route(ALL_OUTPUTS, "mono", 0.25);
// cartridge
GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "chessmstdm_cart");
SOFTWARE_LIST(config, "cart_list").set_original("chessmstdm");
}
// ROM definition
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( chessmst )
ROM_REGION( 0x2800, "maincpu", 0 )
ROM_LOAD("056.bin", 0x0000, 0x0400, CRC(2b90e5d3) SHA1(c47445964b2e6cb11bd1f27e395cf980c97af196) ) // U505
ROM_LOAD("057.bin", 0x0400, 0x0400, CRC(e666fc56) SHA1(3fa75b82cead81973bea94191a5c35f0acaaa0e6) ) // "
ROM_LOAD("058.bin", 0x0800, 0x0400, CRC(6a17fbec) SHA1(019051e93a5114477c50eaa87e1ff01b02eb404d) ) // "
ROM_LOAD("059.bin", 0x0c00, 0x0400, CRC(e96e3d07) SHA1(20fab75f206f842231f0414ebc473ce2a7371e7f) ) // "
ROM_LOAD("060.bin", 0x1000, 0x0400, CRC(0e31f000) SHA1(daac924b79957a71a4b276bf2cef44badcbe37d3) ) // "
ROM_LOAD("061.bin", 0x1400, 0x0400, CRC(69ad896d) SHA1(25d999b59d4cc74bd339032c26889af00e64df60) ) // "
ROM_LOAD("062.bin", 0x1800, 0x0400, CRC(c42925fe) SHA1(c42d8d7c30a9b6d91ac994cec0cc2723f41324e9) ) // "
ROM_LOAD("063.bin", 0x1c00, 0x0400, CRC(86be4cdb) SHA1(741f984c15c6841e227a8722ba30cf9e6b86d878) ) // "
ROM_LOAD("064.bin", 0x2000, 0x0400, CRC(e82f5480) SHA1(38a939158052f5e6484ee3725b86e522541fe4aa) ) // "
ROM_LOAD("065.bin", 0x2400, 0x0400, CRC(4ec0e92c) SHA1(0b748231a50777391b04c1778750fbb46c21bee8) ) // "
ROM_LOAD("bm056.d208", 0x0000, 0x0400, CRC(2b90e5d3) SHA1(c47445964b2e6cb11bd1f27e395cf980c97af196) ) // U505
ROM_LOAD("bm057.d209", 0x0400, 0x0400, CRC(e666fc56) SHA1(3fa75b82cead81973bea94191a5c35f0acaaa0e6) ) // "
ROM_LOAD("bm058.d210", 0x0800, 0x0400, CRC(6a17fbec) SHA1(019051e93a5114477c50eaa87e1ff01b02eb404d) ) // "
ROM_LOAD("bm059.d211", 0x0c00, 0x0400, CRC(e96e3d07) SHA1(20fab75f206f842231f0414ebc473ce2a7371e7f) ) // "
ROM_LOAD("bm060.d212", 0x1000, 0x0400, CRC(0e31f000) SHA1(daac924b79957a71a4b276bf2cef44badcbe37d3) ) // "
ROM_LOAD("bm061.d213", 0x1400, 0x0400, CRC(69ad896d) SHA1(25d999b59d4cc74bd339032c26889af00e64df60) ) // "
ROM_LOAD("bm062.d214", 0x1800, 0x0400, CRC(c42925fe) SHA1(c42d8d7c30a9b6d91ac994cec0cc2723f41324e9) ) // "
ROM_LOAD("bm063.d215", 0x1c00, 0x0400, CRC(86be4cdb) SHA1(741f984c15c6841e227a8722ba30cf9e6b86d878) ) // "
ROM_LOAD("bm064.d216", 0x2000, 0x0400, CRC(e82f5480) SHA1(38a939158052f5e6484ee3725b86e522541fe4aa) ) // "
ROM_LOAD("bm065.d217", 0x2400, 0x0400, CRC(4ec0e92c) SHA1(0b748231a50777391b04c1778750fbb46c21bee8) ) // "
ROM_END
ROM_START( chessmsta )
@ -391,19 +286,14 @@ ROM_START( chessmsta )
ROM_LOAD("bm108.d205", 0x2000, 0x0800, CRC(6e69ace3) SHA1(e099b6b6cc505092f64b8d51ab9c70aa64f58f70) BAD_DUMP ) // U2616D45 - problem with d3
ROM_END
ROM_START( chessmstdm )
ROM_REGION( 0x4000, "maincpu", 0 )
ROM_LOAD("002.d224", 0x0000, 0x2000, CRC(bed56fef) SHA1(dad0f8ddbd9b10013a5bdcc09ee6db39cfb26b78) ) // U2364D45
ROM_LOAD("201.d225", 0x2000, 0x2000, CRC(c9dc7f29) SHA1(a3e1b66d0e15ffe83a9165d15c4a83013852c2fe) ) // "
ROM_END
} // anonymous namespace
// Driver
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
COMP( 1984, chessmst, 0, 0, chessmst, chessmst, chessmst_state, empty_init, "VEB Mikroelektronik \"Karl Marx\" Erfurt", "Chess-Master (set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
COMP( 1984, chessmsta, chessmst, 0, chessmsta, chessmst, chessmst_state, empty_init, "VEB Mikroelektronik \"Karl Marx\" Erfurt", "Chess-Master (set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING | MACHINE_CLICKABLE_ARTWORK )
/******************************************************************************
Drivers
******************************************************************************/
COMP( 1987, chessmstdm, 0, 0, chessmstdm, chessmstdm, chessmst_state, empty_init, "VEB Mikroelektronik \"Karl Marx\" Erfurt", "Chess-Master Diamond", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
CONS( 1984, chessmst, 0, 0, chessmst, chessmst, chessmst_state, empty_init, "VEB Mikroelektronik \"Karl Marx\" Erfurt", "Chess-Master (set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
CONS( 1984, chessmsta, chessmst, 0, chessmsta, chessmst, chessmst_state, empty_init, "VEB Mikroelektronik \"Karl Marx\" Erfurt", "Chess-Master (set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING | MACHINE_CLICKABLE_ARTWORK )

View File

@ -0,0 +1,324 @@
// license:BSD-3-Clause
// copyright-holders:Sandro Ronco, hap
/******************************************************************************
Chess-Master Diamond (G-5004-500)
The chess engine is a continuation of the older Chess-Master model. So it
plays quite weak when compared with other chess computers from 1987.
Hardware notes:
- UA880 Z80 @ 4MHz
- 2*Z80 PIO
- 16KB ROM (2*U2364D), 1.5KB RAM (6*U214D)
- 4-digit 16seg display
- module slot for opening book/endgame
- chessboard with 64 hall sensors, 64+2 leds, beeper
TODO:
- the 555 only connects to BSTB pin, why is the data_b_write workaround needed?
******************************************************************************/
#include "emu.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
#include "cpu/z80/z80.h"
#include "machine/clock.h"
#include "machine/z80pio.h"
#include "machine/sensorboard.h"
#include "sound/beep.h"
#include "video/pwm.h"
#include "speaker.h"
// internal artwork
#include "chessmstdm.lh"
namespace {
class chessmstdm_state : public driver_device
{
public:
chessmstdm_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_pio(*this, "z80pio%u", 0),
m_board(*this, "board"),
m_led_pwm(*this, "led_pwm"),
m_digit_pwm(*this, "digit_pwm"),
m_beeper(*this, "beeper"),
m_inputs(*this, "IN.%u", 0),
m_digits(*this, "digit%u", 0U)
{ }
DECLARE_INPUT_CHANGED_MEMBER(reset_button);
void chessmstdm(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
required_device<z80_device> m_maincpu;
required_device_array<z80pio_device, 2> m_pio;
required_device<sensorboard_device> m_board;
required_device<pwm_display_device> m_led_pwm;
required_device<pwm_display_device> m_digit_pwm;
required_device<beep_device> m_beeper;
required_ioport_array<2> m_inputs;
output_finder<4> m_digits;
void chessmstdm_mem(address_map &map);
void chessmstdm_io(address_map &map);
void digits_w(u8 data);
void pio1_port_a_w(u8 data);
void pio1_port_b_w(u8 data);
u8 pio2_port_a_r();
void pio2_port_b_w(u8 data);
void update_leds();
void update_digits();
u16 m_matrix = 0;
u8 m_led_data = 0;
u8 m_direct_leds = 0;
u8 m_digit_matrix = 0;
int m_digit_dot = 0;
u16 m_digit_data = 0;
};
void chessmstdm_state::machine_start()
{
m_digits.resolve();
// register for savestates
save_item(NAME(m_matrix));
save_item(NAME(m_direct_leds));
save_item(NAME(m_led_data));
save_item(NAME(m_digit_matrix));
save_item(NAME(m_digit_dot));
save_item(NAME(m_digit_data));
}
void chessmstdm_state::machine_reset()
{
// reset digit shift registers
m_digit_data = 0;
update_digits();
}
/******************************************************************************
I/O
******************************************************************************/
void chessmstdm_state::update_digits()
{
u16 digit_data = bitswap<16>(m_digit_data, 3,5,12,10,14,1,2,13,8,6,11,15,7,9,4,0);
m_digit_pwm->matrix(m_digit_matrix, digit_data | (m_digit_dot << 16));
}
void chessmstdm_state::digits_w(u8 data)
{
// d0-d3: shift digit segment data into 4015 shift registers
m_digit_data = (m_digit_data << 4) | (data & 0x0f);
// d4-d7: digit select
m_digit_matrix = (data >> 4) & 0x0f;
update_digits();
}
void chessmstdm_state::update_leds()
{
m_led_pwm->matrix((m_matrix & 0xff) | (m_direct_leds << 8), m_led_data);
}
void chessmstdm_state::pio1_port_a_w(u8 data)
{
// d0-d7: chessboard led data
m_led_data = ~data;
update_leds();
}
void chessmstdm_state::pio1_port_b_w(u8 data)
{
// d2: input mux highest bit
m_matrix = (m_matrix & 0xff) | ((data & 0x04) << 6);
// d3: enable beeper
m_beeper->set_state(BIT(data, 3));
// d4: digits DP
m_digit_dot = BIT(data, 4);
update_digits();
// d5: monitor led, d6: playmode led
m_direct_leds = data >> 5 & 3;
update_leds();
// d4 and d7 also go to cartslot, but unused
}
u8 chessmstdm_state::pio2_port_a_r()
{
u8 data = 0;
// read chessboard sensors
for (int i = 0; i < 8; i++)
if (BIT(m_matrix, i))
data |= m_board->read_file(i);
// read other buttons
if (m_matrix & 0x100)
data |= m_inputs[0]->read();
return ~data;
}
void chessmstdm_state::pio2_port_b_w(u8 data)
{
// d0-d7: input mux/led select
m_matrix = (data & 0xff) | (m_matrix & ~0xff);
update_leds();
}
/******************************************************************************
Address Maps
******************************************************************************/
void chessmstdm_state::chessmstdm_mem(address_map &map)
{
map.unmap_value_high();
map(0x0000, 0x3fff).rom();
map(0x4000, 0x7fff).r("cartslot", FUNC(generic_slot_device::read_rom));
map(0x8000, 0x8bff).ram();
}
void chessmstdm_state::chessmstdm_io(address_map &map)
{
map.unmap_value_high();
map.global_mask(0x7f);
//map(0x00, 0x03).mirror(0x70) read/write to both PIOs, but not used by software
map(0x04, 0x07).mirror(0x70).rw(m_pio[0], FUNC(z80pio_device::read), FUNC(z80pio_device::write));
map(0x08, 0x0b).mirror(0x70).rw(m_pio[1], FUNC(z80pio_device::read), FUNC(z80pio_device::write));
map(0x4c, 0x4c).mirror(0x03).w(FUNC(chessmstdm_state::digits_w));
}
/******************************************************************************
Input Ports
******************************************************************************/
INPUT_CHANGED_MEMBER(chessmstdm_state::reset_button)
{
// pressing both monitor+view buttons buttons causes a reset
const bool reset = (m_inputs[1]->read() & 0x03) == 0x03;
m_maincpu->set_input_line(INPUT_LINE_RESET, reset ? ASSERT_LINE : CLEAR_LINE);
if (reset)
machine_reset();
}
static INPUT_PORTS_START( chessmstdm )
PORT_START("IN.0")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Move Fore") PORT_CODE(KEYCODE_RIGHT)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Move Back") PORT_CODE(KEYCODE_LEFT)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Board") PORT_CODE(KEYCODE_B)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Match / Time") PORT_CODE(KEYCODE_M)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Parameter / Information") PORT_CODE(KEYCODE_I)
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Selection / Dialogue") PORT_CODE(KEYCODE_S)
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Function / Notation") PORT_CODE(KEYCODE_F)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD)
PORT_START("IN.1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("Monitor") PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmstdm_state, reset_button, 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME("View") PORT_CODE(KEYCODE_F2) PORT_CHANGED_MEMBER(DEVICE_SELF, chessmstdm_state, reset_button, 0)
INPUT_PORTS_END
/******************************************************************************
Machine Configs
******************************************************************************/
static const z80_daisy_config chessmstdm_daisy_chain[] =
{
{ "z80pio1" },
{ nullptr }
};
void chessmstdm_state::chessmstdm(machine_config &config)
{
// basic machine hardware
Z80(config, m_maincpu, 8_MHz_XTAL / 2);
m_maincpu->set_addrmap(AS_PROGRAM, &chessmstdm_state::chessmstdm_mem);
m_maincpu->set_addrmap(AS_IO, &chessmstdm_state::chessmstdm_io);
m_maincpu->set_daisy_config(chessmstdm_daisy_chain);
auto &strobe(CLOCK(config, "strobe", 500)); // from 555 timer, 50% duty
strobe.signal_handler().set(m_pio[1], FUNC(z80pio_device::strobe_b));
strobe.signal_handler().append([this](int) { m_pio[1]->data_b_write(m_matrix); });
Z80PIO(config, m_pio[0], 8_MHz_XTAL / 2);
m_pio[0]->out_pa_callback().set(FUNC(chessmstdm_state::pio1_port_a_w));
m_pio[0]->out_pb_callback().set(FUNC(chessmstdm_state::pio1_port_b_w));
m_pio[0]->in_pb_callback().set_ioport("IN.1");
Z80PIO(config, m_pio[1], 8_MHz_XTAL / 2);
m_pio[1]->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_pio[1]->in_pa_callback().set(FUNC(chessmstdm_state::pio2_port_a_r));
m_pio[1]->out_pb_callback().set(FUNC(chessmstdm_state::pio2_port_b_w));
SENSORBOARD(config, m_board);
m_board->set_type(sensorboard_device::MAGNETS);
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_digit_pwm).set_size(4, 17);
m_digit_pwm->set_segmask(0xf, 0x1ffff);
m_digit_pwm->output_digit().set([this](offs_t offset, u64 data) { m_digits[offset] = data; });
PWM_DISPLAY(config, m_led_pwm).set_size(8+2, 8);
config.set_default_layout(layout_chessmstdm);
// sound hardware
SPEAKER(config, "speaker").front_center();
BEEP(config, m_beeper, 1000).add_route(ALL_OUTPUTS, "speaker", 0.25);
// cartridge
GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "chessmstdm_cart");
SOFTWARE_LIST(config, "cart_list").set_original("chessmstdm");
}
/******************************************************************************
ROM Definitions
******************************************************************************/
ROM_START( chessmstdm )
ROM_REGION( 0x4000, "maincpu", 0 )
ROM_LOAD("002.d224", 0x0000, 0x2000, CRC(bed56fef) SHA1(dad0f8ddbd9b10013a5bdcc09ee6db39cfb26b78) ) // U2364D45
ROM_LOAD("201.d225", 0x2000, 0x2000, CRC(c9dc7f29) SHA1(a3e1b66d0e15ffe83a9165d15c4a83013852c2fe) ) // "
ROM_END
} // anonymous namespace
/******************************************************************************
Drivers
******************************************************************************/
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
CONS( 1987, chessmstdm, 0, 0, chessmstdm, chessmstdm, chessmstdm_state, empty_init, "VEB Mikroelektronik \"Karl Marx\" Erfurt", "Chess-Master Diamond", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )

View File

@ -19,10 +19,10 @@ BTANB:
Elite A/S Challenger (EAS)
---------------------------------
This came out in 1982. 2 program updates were released in 1983 and 1984,
named Budapest and Glasgow, places where Fidelity won chess computer matches.
A/S stands for auto sensory, it's the 1st Fidelity board with magnet sensors.
The magnetic chessboard was licensed from AVE Micro Systems, in fact, the
PC model board is the same one as in AVE's ARB (ave_arb.cpp driver).
named Budapest and Glasgow, places where Fidelity competed in chess computer
matches (they won it in 1983). A/S stands for auto sensory, it's the 1st
Fidelity board with magnet sensors. The magnetic chessboard was licensed from
AVE Micro Systems, in fact, the PC model board is the same one as in AVE's ARB.
hardware overview:
- 8*8 magnet sensors, 11 buttons, 8*(8+1) LEDs + 4*7seg LEDs

View File

@ -474,16 +474,16 @@ license:CC0
<element name="9.0" ref="ledr"> <bounds x="115.5" y="75" width="2" height="2" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x80"><bounds x="118" y="20" width="4" height="4" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x40"><bounds x="118" y="27" width="4" height="4" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x20"><bounds x="118" y="34" width="4" height="4" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x10"><bounds x="118" y="41" width="4" height="4" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x08"><bounds x="118" y="48" width="4" height="4" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x04"><bounds x="118" y="55" width="4" height="4" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x02"><bounds x="118" y="62" width="4" height="4" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x01"><bounds x="118" y="69" width="4" height="4" /></element>
<element ref="hlb" inputtag="EXTRA" inputmask="0x02"><bounds x="108" y="79" width="4" height="4" /></element>
<element ref="hlb" inputtag="EXTRA" inputmask="0x01"><bounds x="122" y="79" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x80"><bounds x="118" y="20" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x40"><bounds x="118" y="27" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x20"><bounds x="118" y="34" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x10"><bounds x="118" y="41" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x08"><bounds x="118" y="48" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x04"><bounds x="118" y="55" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x02"><bounds x="118" y="62" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x01"><bounds x="118" y="69" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.1" inputmask="0x02"><bounds x="108" y="79" width="4" height="4" /></element>
<element ref="hlb" inputtag="IN.1" inputmask="0x01"><bounds x="122" y="79" width="4" height="4" /></element>
<element ref="cwhite"><bounds x="17" y="4" width="81" height="81" /></element>
<group ref="sb_board"><bounds x="17.5" y="4.5" width="80" height="80" /></group>

View File

@ -411,21 +411,21 @@ license:CC0
<element ref="text_move_fore"> <bounds x="115" y="84" width="12" height="2" /></element>
<element ref="text_playmode"> <bounds x="103" y="74" width="10" height="2" /></element>
<element name="dled0" ref="led"> <bounds x="110.5" y="20.63" width="1.5" height="1.5" /> </element>
<element name="dled1" ref="led"> <bounds x="112" y="74.13" width="1.5" height="1.5" /> </element>
<element name="reset_line0" ref="black_rect"> <bounds x="119.4" y="24.2" width="0.2" height="1.6" /> </element>
<element name="reset_line1" ref="black_rect"> <bounds x="116.7" y="25.0" width="2.9" height="0.2" /> </element>
<element name="8.a" ref="led"> <bounds x="110.5" y="20.63" width="1.5" height="1.5" /> </element>
<element name="9.a" ref="led"> <bounds x="112" y="74.13" width="1.5" height="1.5" /> </element>
<element ref="black_rect"> <bounds x="119.4" y="24.2" width="0.2" height="1.6" /> </element>
<element ref="black_rect"> <bounds x="116.7" y="25.0" width="2.9" height="0.2" /> </element>
<element ref="hlb" inputtag="EXTRA" inputmask="0x01"><bounds x="117" y="19" width="5" height="5" /></element>
<element ref="hlb" inputtag="EXTRA" inputmask="0x02"><bounds x="117" y="26" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x40"><bounds x="117" y="33" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x20"><bounds x="117" y="40" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x10"><bounds x="117" y="47" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x08"><bounds x="117" y="54" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x04"><bounds x="117" y="61" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x80"><bounds x="117" y="68" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x02"><bounds x="105" y="78" width="5" height="5" /></element>
<element ref="hlb" inputtag="BUTTONS" inputmask="0x01"><bounds x="119" y="78" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.1" inputmask="0x01"><bounds x="117" y="19" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.1" inputmask="0x02"><bounds x="117" y="26" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x40"><bounds x="117" y="33" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x20"><bounds x="117" y="40" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x10"><bounds x="117" y="47" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x08"><bounds x="117" y="54" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x04"><bounds x="117" y="61" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x80"><bounds x="117" y="68" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x02"><bounds x="105" y="78" width="5" height="5" /></element>
<element ref="hlb" inputtag="IN.0" inputmask="0x01"><bounds x="119" y="78" width="5" height="5" /></element>
<!-- panel 16seg leds -->
<element name="display_background" ref="black_rect"> <bounds x="101" y="4" width="26" height="9.2" /> </element>

View File

@ -10271,9 +10271,11 @@ ccmk2a //
chmate //
@source:chessmst.cpp
chessmst //
chessmsta //
chessmstdm //
chessmst
chessmsta
@source:chessmstdm.cpp
chessmstdm
@source:chexx.cpp
chexx83 // 1983 ICE

View File

@ -170,6 +170,7 @@ channelf.cpp
chaos.cpp
chessmate.cpp
chessmst.cpp
chessmstdm.cpp
cit101.cpp
cit101xl.cpp
cit1500.cpp