From 80ce72877e6b1cf0b4bd8afe0a46b6a477573310 Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 19 Feb 2022 20:57:41 +0100 Subject: [PATCH] New working machines -------------------- Chesster Phantom [hap, Berger] --- src/mame/drivers/fidel_phantom.cpp | 399 +++++++++++----- src/mame/layout/fidel_cphantom.lay | 713 +++++++++++++++++++++++++++++ src/mame/mame.lst | 1 + 3 files changed, 1003 insertions(+), 110 deletions(-) create mode 100644 src/mame/layout/fidel_cphantom.lay diff --git a/src/mame/drivers/fidel_phantom.cpp b/src/mame/drivers/fidel_phantom.cpp index bc06552e9fd..5b444572f79 100644 --- a/src/mame/drivers/fidel_phantom.cpp +++ b/src/mame/drivers/fidel_phantom.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause -// copyright-holders:hap,Sandro Ronco +// copyright-holders:hap, Sandro Ronco +// thanks-to:Berger /****************************************************************************** Fidelity Phantom (model 6100) @@ -10,12 +11,16 @@ the outside. After Fidelity was taken over by H+G, it was rereleased in 1990 as Mephisto Phantom. This is assumed to be identical. Hardware notes: -- R65C02P4, XTAL marked 4.91?200 +- PCB label 510.1128A01 +- R65C02P4, XTAL marked 4.915200 - 2*32KB ROM 27C256-15, 8KB RAM MS6264L-10 - LCD driver, display panel for digits -- magnetized x/y motor under chessboard, chesspieces have magnet underneath +- magnetized x/y DC motors under chessboard, chesspieces have magnet underneath - piezo speaker, LEDs, 8*8 chessboard buttons -- PCB label 510.1128A01 + +Chesster Phantom is on similar base hardware, and adds the Chesster voice to it, +using the same ROM as the original Chesster. It also has a motion sensor at the +front and 2 leds to mimick eyes. To play, wait until the motor is finished before making a move. At boot-up, the computer will do a self-test. @@ -24,23 +29,30 @@ spawn block and place it at the designated box at the edge of the chessboard. TODO: - sensorboard undo buffer goes out of control, probably not worth solving this issue +- cphantom artwork should be green instead of beige +- motor position in artwork? ******************************************************************************/ #include "emu.h" + #include "cpu/m6502/r65c02.h" #include "machine/sensorboard.h" #include "machine/timer.h" #include "sound/dac.h" #include "video/pwm.h" + #include "speaker.h" // internal artwork +#include "fidel_cphantom.lh" // clickable #include "fidel_phantom.lh" // clickable namespace { +// Phantom 6100 / shared + class phantom_state : public driver_device { public: @@ -51,59 +63,67 @@ public: m_dac(*this, "dac"), m_board(*this, "board"), m_display(*this, "display"), - m_input(*this, "IN.0"), + m_inputs(*this, "IN.%u", 0), m_out_motor(*this, "motor.%u", 0U) { } - void fphantom(machine_config &config); - void init_fphantom(); + void phantom(machine_config &config); + void init_phantom(); protected: virtual void machine_start() override; virtual void machine_reset() override; -private: // devices/pointers required_device m_maincpu; required_memory_bank m_rombank; - required_device m_dac; + optional_device m_dac; required_device m_board; required_device m_display; - required_ioport m_input; + optional_ioport_array<2> m_inputs; output_finder<5> m_out_motor; - void main_map(address_map &map); + // address maps + virtual void main_map(address_map &map); + // I/O handlers + void init_motors(); + void check_rotation(); TIMER_DEVICE_CALLBACK_MEMBER(motors_timer); - void update_lcd(); - void control_w(offs_t offset, u8 data); + void update_pieces_position(int state); + + void update_lcd(u8 select); + virtual void control_w(offs_t offset, u8 data); void lcd_w(offs_t offset, u8 data); void motors_w(u8 data); - u8 input_r(offs_t offset); + virtual u8 input_r(offs_t offset); u8 motors_r(offs_t offset); u8 irq_ack_r(); u8 hmotor_ff_clear_r(); u8 vmotor_ff_clear_r(); - void update_pieces_position(int state); - uint8_t m_select; - uint32_t m_lcd_data; - uint8_t m_motors_ctrl; - uint8_t m_hmotor_pos; - uint8_t m_vmotor_pos; - bool m_vmotor_sensor0_ff; - bool m_vmotor_sensor1_ff; - bool m_hmotor_sensor0_ff; - bool m_hmotor_sensor1_ff; - int m_piece; - bool m_piece_collision; - uint8_t m_pieces_map[0x40][0x40]; + u8 m_mux = 0; + u8 m_select = 0; + u32 m_lcd_data = 0; + + u8 m_motors_ctrl; + int m_hmotor_pos; + int m_vmotor_pos; + bool m_vmotor_sensor0_ff; + bool m_vmotor_sensor1_ff; + bool m_hmotor_sensor0_ff; + bool m_hmotor_sensor1_ff; + int m_piece; + bool m_piece_collision; + u8 m_pieces_map[0x40][0x40]; }; void phantom_state::machine_start() { m_out_motor.resolve(); + // register for savestates + save_item(NAME(m_mux)); save_item(NAME(m_select)); save_item(NAME(m_lcd_data)); save_item(NAME(m_motors_ctrl)); @@ -120,25 +140,54 @@ void phantom_state::machine_start() void phantom_state::machine_reset() { - m_select = 0; - m_lcd_data = 0; - m_motors_ctrl = 0; - m_hmotor_pos = 0xff; - m_vmotor_pos = 0xff; - m_vmotor_sensor0_ff = false; - m_vmotor_sensor1_ff = false; - m_hmotor_sensor0_ff = false; - m_hmotor_sensor1_ff = false; - m_piece = 0; - m_piece_collision = false; - memset(m_pieces_map, 0, sizeof(m_pieces_map)); - + init_motors(); m_rombank->set_entry(0); } -void phantom_state::init_fphantom() +void phantom_state::init_phantom() { - m_rombank->configure_entries(0, 2, memregion("rombank")->base(), 0x4000); + int numbanks = memregion("rombank")->bytes() / 0x4000; + m_rombank->configure_entries(0, numbanks, memregion("rombank")->base(), 0x4000); +} + +// Chesster Phantom + +class chessterp_state : public phantom_state +{ +public: + chessterp_state(const machine_config &mconfig, device_type type, const char *tag) : + phantom_state(mconfig, type, tag), + m_eye_led(*this, "eye_led") + { } + + void cphantom(machine_config &config); + +protected: + virtual void machine_start() override; + +private: + output_finder<> m_eye_led; + + virtual void main_map(address_map &map) override; + + TIMER_DEVICE_CALLBACK_MEMBER(nmi_timer); + virtual void control_w(offs_t offset, u8 data) override; + virtual u8 input_r(offs_t offset) override; + + u8 m_select2 = 0; +}; + +void chessterp_state::machine_start() +{ + phantom_state::machine_start(); + + m_eye_led.resolve(); + save_item(NAME(m_select2)); +} + +TIMER_DEVICE_CALLBACK_MEMBER(chessterp_state::nmi_timer) +{ + m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } @@ -147,17 +196,45 @@ void phantom_state::init_fphantom() Motor Sim ******************************************************************************/ +void phantom_state::init_motors() +{ + m_motors_ctrl = 0; + m_hmotor_pos = 0x80; + m_vmotor_pos = 0x80; + m_vmotor_sensor0_ff = false; + m_vmotor_sensor1_ff = false; + m_hmotor_sensor0_ff = false; + m_hmotor_sensor1_ff = false; + m_piece = 0; + m_piece_collision = false; + memset(m_pieces_map, 0, sizeof(m_pieces_map)); +} + +void phantom_state::check_rotation() +{ + if (m_vmotor_pos != 0 && m_vmotor_pos != 0xff) + { + if (m_motors_ctrl & 0x03) m_vmotor_sensor0_ff = true; + if (m_motors_ctrl & 0x02) m_vmotor_sensor1_ff = true; + } + if (m_hmotor_pos != 0 && m_hmotor_pos != 0xff) + { + if (m_motors_ctrl & 0x0c) m_hmotor_sensor0_ff = true; + if (m_motors_ctrl & 0x04) m_hmotor_sensor1_ff = true; + } +} + TIMER_DEVICE_CALLBACK_MEMBER(phantom_state::motors_timer) { - if (m_motors_ctrl & 0x03) m_vmotor_sensor0_ff = true; - if (m_motors_ctrl & 0x02) m_vmotor_sensor1_ff = true; - if (m_motors_ctrl & 0x0c) m_hmotor_sensor0_ff = true; - if (m_motors_ctrl & 0x04) m_hmotor_sensor1_ff = true; + check_rotation(); - if ((m_motors_ctrl & 0x01) && m_vmotor_pos > 0x00) m_vmotor_pos--; - if ((m_motors_ctrl & 0x02) && m_vmotor_pos < 0xff) m_vmotor_pos++; - if ((m_motors_ctrl & 0x04) && m_hmotor_pos > 0x00) m_hmotor_pos--; - if ((m_motors_ctrl & 0x08) && m_hmotor_pos < 0xff) m_hmotor_pos++; + // simulate 1 rotation per each tick + if ((m_motors_ctrl & 0x01) && m_vmotor_pos > 0x00) m_vmotor_pos--; + if ((m_motors_ctrl & 0x02) && m_vmotor_pos < 0xff) m_vmotor_pos++; + if ((m_motors_ctrl & 0x04) && m_hmotor_pos > 0x00) m_hmotor_pos--; + if ((m_motors_ctrl & 0x08) && m_hmotor_pos < 0xff) m_hmotor_pos++; + + check_rotation(); } void phantom_state::update_pieces_position(int state) @@ -170,7 +247,7 @@ void phantom_state::update_pieces_position(int state) x += 12; // check if the magnet is in the center of a square - bool valid_pos = ((m_hmotor_pos & 0x0f) == 0x03 || (m_hmotor_pos & 0x0f) == 0x07) && ((m_vmotor_pos & 0x0f) == 0x09 || (m_vmotor_pos & 0x0f) == 0x0d); + bool valid_pos = ((m_hmotor_pos & 0x0f) > 0 && (m_hmotor_pos & 0x0f) <= 7) && ((m_vmotor_pos & 0x0f) > 8 && (m_vmotor_pos & 0x0f) <= 0xf); if (state) { @@ -212,48 +289,87 @@ void phantom_state::update_pieces_position(int state) I/O ******************************************************************************/ -void phantom_state::update_lcd() +void phantom_state::update_lcd(u8 select) { - u8 mask = (m_select & 0x80) ? 0xff : 0; - for (int i = 0; i < 4; i++) - m_display->write_row(i+1, (m_lcd_data >> (8*i) & 0xff) ^ mask); + // update lcd at any edge + if ((select ^ m_select) & 0x80) + { + u8 mask = (m_select & 0x80) ? 0xff : 0; + for (int i = 0; i < 4; i++) + m_display->write_row(i+1, (m_lcd_data >> (8*i) & 0xff) ^ mask); + } } void phantom_state::control_w(offs_t offset, u8 data) { + u8 lcd_prev = m_select; + // a0-a2,d1: 74259 - uint8_t mask = 1 << offset; + u8 mask = 1 << offset; m_select = (m_select & ~mask) | ((data & 0x02) ? mask : 0); // 74259 Q0-Q3: 7442 a0-a3 // 7442 0-8: led data, input mux // 74259 Q4: led select - m_display->matrix_partial(0, 1, BIT(~m_select, 4), 1 << (m_select & 0xf)); + m_mux = m_select & 0xf; + m_display->matrix_partial(0, 1, BIT(~m_select, 4), 1 << m_mux); // 74259 Q6: bookrom bank m_rombank->set_entry(BIT(m_select, 6)); // 74259 Q7: lcd polarity - update_lcd(); + update_lcd(lcd_prev); +} + +void chessterp_state::control_w(offs_t offset, u8 data) +{ + // chesster version has two 74259, more I/O + u8 lcd_prev = m_select; + u8 nmi_prev = m_select2; + + // a0-a2,d0,d1: 2*74259 + u8 mask = 1 << offset; + m_select = (m_select & ~mask) | ((data & 1) ? mask : 0); + m_select2 = (m_select2 & ~mask) | ((data & 2) ? mask : 0); + + // 74259(both) Q0,Q1: 7442 a0-a3 + // 7442 0-8: led data, input mux + // 74259(1) Q2: led select + m_mux = BIT(m_select, 0) | BIT(m_select2, 0) << 1 | BIT(m_select, 1) << 2 | BIT(m_select2, 1) << 3; + m_display->matrix_partial(0, 1, BIT(~m_select, 2), 1 << m_mux); + + // 74259(2) Q2: eye leds + m_eye_led = BIT(~m_select2, 2); + + // 74259(2) Q3 rising edge: nmi clear + if (~nmi_prev & m_select2 & 8) + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); + + // 74259(1) Q4,Q5, 74259(2) Q4: speechrom bank + m_rombank->set_entry(BIT(m_select, 4) | (BIT(m_select2, 4) << 1) | (BIT(m_select, 5) << 2)); + + // 74259(1) Q7: lcd polarity + update_lcd(lcd_prev); } void phantom_state::motors_w(u8 data) { - // bit 0: vertical motor down - // bit 1: vertical motor up - // bit 2: horizontal motor left - // bit 3: horizontal motor right - // bit 4: electromagnet - // bit 5: speaker + // d0: vertical motor down + // d1: vertical motor up + // d2: horizontal motor left + // d3: horizontal motor right + // d4: electromagnet + for (int i = 0; i < 5; i++) + m_out_motor[i] = BIT(data, i); if ((m_motors_ctrl ^ data) & 0x10) update_pieces_position(BIT(data, 4)); - for (int i = 0; i < 5; i++) - m_out_motor[i] = BIT(data, i); - - m_dac->write(BIT(data, 5)); m_motors_ctrl = data; + + // d5: speaker (not for chesster version, though it still writes to it) + if (m_dac != nullptr) + m_dac->write(BIT(data, 5)); } void phantom_state::lcd_w(offs_t offset, u8 data) @@ -265,47 +381,59 @@ void phantom_state::lcd_w(offs_t offset, u8 data) m_lcd_data = (m_lcd_data & ~mask) | (BIT(data, i * 2) ? mask : 0); mask <<= 8; } - - update_lcd(); } u8 phantom_state::input_r(offs_t offset) { - uint8_t mux = m_select & 0xf; - uint8_t data = 0xff; + u8 data = 0xff; - if (mux == 8) + // buttons + if (m_mux == 8) { - if (BIT(m_input->read(), offset * 2 + 1)) data &= ~0x40; - if (BIT(m_input->read(), offset * 2 + 0)) data &= ~0x80; + if (BIT(m_inputs[0]->read(), offset * 2 + 1)) data &= ~0x40; + if (BIT(m_inputs[0]->read(), offset * 2 + 0)) data &= ~0x80; } + + // chessboard sensors else if (offset < 4) { - if (BIT(m_board->read_file(offset * 2 + 1), mux)) data &= ~0x40; - if (BIT(m_board->read_file(offset * 2 + 0), mux)) data &= ~0x80; + if (BIT(m_board->read_file(offset * 2 + 1), m_mux)) data &= ~0x40; + if (BIT(m_board->read_file(offset * 2 + 0), m_mux)) data &= ~0x80; } + + // captured pieces else { - if (BIT(m_board->read_file( 8 + (offset & 1)), mux)) data &= ~0x40; // black captured pieces - if (BIT(m_board->read_file(11 - (offset & 1)), mux)) data &= ~0x80; // white captured pieces + if (BIT(m_board->read_file( 8 + (offset & 1)), m_mux)) data &= ~0x40; // black + if (BIT(m_board->read_file(11 - (offset & 1)), m_mux)) data &= ~0x80; // white } return data; } +u8 chessterp_state::input_r(offs_t offset) +{ + u8 data = phantom_state::input_r(offset) & 0xfe; + + // d0: motion sensor (simulated here with an arbitrary timer) + int motion = ((machine().time().as_ticks(50) & 0xff) > 0) ? 1 : 0; + return data | motion | (m_inputs[1]->read() & 1); +} + u8 phantom_state::motors_r(offs_t offset) { - uint8_t data = 0xff; + u8 data = 0xff; + // optical rotation sensors switch (offset) { case 0: - if (!m_vmotor_sensor1_ff) data &= ~0x40; - if (!m_hmotor_sensor1_ff) data &= ~0x80; + if (!m_vmotor_sensor1_ff) data &= ~0x40; + if (!m_hmotor_sensor1_ff) data &= ~0x80; break; case 1: - if (!m_vmotor_sensor0_ff) data &= ~0x40; - if (!m_hmotor_sensor0_ff) data &= ~0x80; + if (!m_vmotor_sensor0_ff) data &= ~0x40; + if (!m_hmotor_sensor0_ff) data &= ~0x80; break; } @@ -316,6 +444,7 @@ u8 phantom_state::irq_ack_r() { if (!machine().side_effects_disabled()) m_maincpu->set_input_line(R65C02_IRQ_LINE, CLEAR_LINE); + return 0; } @@ -345,70 +474,109 @@ void phantom_state::main_map(address_map &map) { map(0x0000, 0x1fff).ram(); map(0x2000, 0x2007).mirror(0x00f8).w(FUNC(phantom_state::control_w)); - map(0x2100, 0x2107).w(FUNC(phantom_state::lcd_w)).nopr(); - map(0x2200, 0x2200).w(FUNC(phantom_state::motors_w)); - map(0x2400, 0x2405).r(FUNC(phantom_state::input_r)); - map(0x2406, 0x2407).r(FUNC(phantom_state::motors_r)); - map(0x2500, 0x25ff).r(FUNC(phantom_state::hmotor_ff_clear_r)); - map(0x2600, 0x2600).r(FUNC(phantom_state::vmotor_ff_clear_r)); - map(0x2700, 0x2700).r(FUNC(phantom_state::irq_ack_r)); + map(0x2100, 0x2107).mirror(0x00f8).w(FUNC(phantom_state::lcd_w)).nopr(); + map(0x2200, 0x2200).mirror(0x00ff).w(FUNC(phantom_state::motors_w)); + map(0x2400, 0x2405).mirror(0x00f8).r(FUNC(phantom_state::input_r)); + map(0x2406, 0x2407).mirror(0x00f8).r(FUNC(phantom_state::motors_r)); + map(0x2500, 0x2500).mirror(0x00ff).r(FUNC(phantom_state::hmotor_ff_clear_r)); + map(0x2600, 0x2600).mirror(0x00ff).r(FUNC(phantom_state::vmotor_ff_clear_r)); + map(0x2700, 0x2700).mirror(0x00ff).r(FUNC(phantom_state::irq_ack_r)); map(0x4000, 0x7fff).bankr("rombank"); map(0x8000, 0xffff).rom(); } +void chessterp_state::main_map(address_map &map) +{ + phantom_state::main_map(map); + map(0x2300, 0x2300).mirror(0x00ff).w("speech", FUNC(dac_byte_interface::data_w)); +} + /****************************************************************************** Input Ports ******************************************************************************/ -static INPUT_PORTS_START( fphantom ) +static INPUT_PORTS_START( phantom ) PORT_START("IN.0") - PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Verify / Problem") - PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Option / Time") - PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Level / New") - PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Take Back / Replay") - PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Hint / Info") - PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Move / Alternate") - PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Auto / Stop") - PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear") + PORT_BIT(0x001, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_V) PORT_NAME("Verify / Problem") + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_O) PORT_NAME("Option / Time") + PORT_BIT(0x004, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_L) PORT_NAME("Level / New") + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Take Back / Replay") + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Hint / Info") + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Move / Alternate") + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Auto / Stop") + PORT_BIT(0x080, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Clear") PORT_BIT(0x100, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_S) PORT_NAME("Shift") PORT_BIT(0x200, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_BIT(0x400, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_BIT(0x800, IP_ACTIVE_HIGH, IPT_UNUSED) INPUT_PORTS_END +static INPUT_PORTS_START( cphantom ) + PORT_INCLUDE( phantom ) + + PORT_MODIFY("IN.0") + PORT_BIT(0x002, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_O) PORT_NAME("Option / Replay") + PORT_BIT(0x008, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) PORT_NAME("Info / Auto") + PORT_BIT(0x010, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) PORT_NAME("Take Back / Repeat") + PORT_BIT(0x020, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Hint / Yes") + PORT_BIT(0x040, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_M) PORT_NAME("Move / No/Stop") + + PORT_START("IN.1") // motion sensor is inverted here, eg. hold down key to pretend noone's there + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F1) PORT_NAME("Motion Sensor") +INPUT_PORTS_END + /****************************************************************************** Machine Configs ******************************************************************************/ -void phantom_state::fphantom(machine_config &config) +void phantom_state::phantom(machine_config &config) { - /* basic machine hardware */ - R65C02(config, m_maincpu, 4.9152_MHz_XTAL); // R65C02P4 - m_maincpu->set_periodic_int(FUNC(phantom_state::irq0_line_assert), attotime::from_hz(600)); // guessed + // basic machine hardware + R65C02(config, m_maincpu, 4.9152_MHz_XTAL); // R65C02P4 or RP65C02G m_maincpu->set_addrmap(AS_PROGRAM, &phantom_state::main_map); + const attotime irq_period = attotime::from_hz(4.9152_MHz_XTAL / 0x2000); // 4060, 600Hz + m_maincpu->set_periodic_int(FUNC(phantom_state::irq0_line_assert), irq_period); + + TIMER(config, "motors_timer").configure_periodic(FUNC(phantom_state::motors_timer), irq_period * 5); + SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS); m_board->set_size(12, 8); m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess)); m_board->set_delay(attotime::from_msec(100)); - TIMER(config, "motors_timer").configure_periodic(FUNC(phantom_state::motors_timer), attotime::from_hz(120)); - - /* video hardware */ + // video hardware PWM_DISPLAY(config, m_display).set_size(1+4, 9); m_display->set_segmask(0x1e, 0x7f); config.set_default_layout(layout_fidel_phantom); - /* sound hardware */ + // sound hardware SPEAKER(config, "speaker").front_center(); DAC_1BIT(config, m_dac).add_route(ALL_OUTPUTS, "speaker", 0.25); } +void chessterp_state::cphantom(machine_config &config) +{ + phantom(config); + + // basic machine hardware + const attotime nmi_period = attotime::from_hz(4.9152_MHz_XTAL / 0x200); // 4060, 9.6kHz + timer_device &nmi_clock(TIMER(config, "nmi_clock")); + nmi_clock.configure_periodic(FUNC(chessterp_state::nmi_timer), nmi_period); + nmi_clock.set_start_delay(nmi_period / 2); // interleaved with irq_period + + config.set_default_layout(layout_fidel_cphantom); + + // sound hardware + config.device_remove("dac"); + DAC_8BIT_R2R(config, "speech").add_route(ALL_OUTPUTS, "speaker", 0.5); +} + /****************************************************************************** @@ -423,6 +591,15 @@ ROM_START( fphantom ) // model 6100, PCB label 510.1128A01 ROM_LOAD("u_4_white.u4", 0x0000, 0x8000, CRC(e4181ba2) SHA1(1f77d1867c6f566be98645fc252a01108f412c96) ) // 27C256 ROM_END + +ROM_START( cphantom ) // model 6126, PCB label 510.1128D01 + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD("pv.u3", 0x8000, 0x8000, CRC(450a9ab5) SHA1(8392c76cf18cd6f8b17c8b12fac40c5cea874941) ) // 27C256 + + ROM_REGION( 0x20000, "rombank", 0 ) + ROM_LOAD("101-1091b02.u4", 0x0000, 0x20000, CRC(fa370e88) SHA1(a937c8f1ec295cf9539d12466993974e40771493) ) // AMI, 27C010 or equivalent +ROM_END + } // anonymous namespace @@ -431,5 +608,7 @@ ROM_END Drivers ******************************************************************************/ -// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS -CONS( 1988, fphantom, 0, 0, fphantom, fphantom, phantom_state, init_fphantom, "Fidelity Electronics", "Phantom Chess Challenger", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS | MACHINE_MECHANICAL ) +// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS +CONS( 1988, fphantom, 0, 0, phantom, phantom, phantom_state, init_phantom, "Fidelity Electronics", "Phantom (Fidelity)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS | MACHINE_MECHANICAL ) + +CONS( 1991, cphantom, 0, 0, cphantom, cphantom, chessterp_state, init_phantom, "Fidelity Electronics", "Chesster Phantom", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS | MACHINE_MECHANICAL ) diff --git a/src/mame/layout/fidel_cphantom.lay b/src/mame/layout/fidel_cphantom.lay new file mode 100644 index 00000000000..3db9aa3124e --- /dev/null +++ b/src/mame/layout/fidel_cphantom.lay @@ -0,0 +1,713 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mame/mame.lst b/src/mame/mame.lst index f20bda7b9ee..12e3071e33d 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -14026,6 +14026,7 @@ granits // RCS miniscco @source:fidel_phantom.cpp +cphantom // fphantom // @source:fidel_sc12.cpp