summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/mephisto_mm1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/mephisto_mm1.cpp')
-rw-r--r--src/mame/drivers/mephisto_mm1.cpp201
1 files changed, 181 insertions, 20 deletions
diff --git a/src/mame/drivers/mephisto_mm1.cpp b/src/mame/drivers/mephisto_mm1.cpp
index 26abdf2f583..1e157ba7b4b 100644
--- a/src/mame/drivers/mephisto_mm1.cpp
+++ b/src/mame/drivers/mephisto_mm1.cpp
@@ -10,7 +10,8 @@ Initially, the module itself didn't have a name. It was only later in retrospect
after the release of Modul MM II that it became known as the MM I.
Hardware notes:
-- CDP1806 @ 8MHz, 6.5V
+- PCB label: HGS 10 121 01
+- CDP1806 @ 8MHz, 6.5V (IRQ from internal timer)
- 32KB ROM (2*D27128, or HN613256P)
- 4KB RAM (2*HM6116LP-3)
- CDP1853CE, CD4011BE, 3*40373BP, 4556BE
@@ -55,6 +56,7 @@ public:
protected:
virtual void machine_start() override;
+ virtual void machine_reset() override;
private:
// devices/pointers
@@ -62,16 +64,62 @@ private:
required_device<sensorboard_device> m_board;
required_device<pwm_display_device> m_display;
required_device<dac_bit_interface> m_dac;
- required_ioport_array<4> m_inputs;
+ required_ioport_array<8> m_inputs;
// address maps
void mm1_map(address_map &map);
void mm1_io(address_map &map);
+ // I/O handlers
+ INTERRUPT_GEN_MEMBER(interrupt);
+ void update_display();
+ DECLARE_READ_LINE_MEMBER(clear_r);
+ DECLARE_WRITE_LINE_MEMBER(q_w);
+ DECLARE_WRITE8_MEMBER(sound_w);
+ DECLARE_WRITE8_MEMBER(lcd_w);
+ DECLARE_WRITE8_MEMBER(board_w);
+ DECLARE_WRITE8_MEMBER(led_w);
+ DECLARE_WRITE8_MEMBER(keypad_w);
+ DECLARE_READ8_MEMBER(board_r);
+ template<int P> DECLARE_READ_LINE_MEMBER(keypad_r);
+
+ bool m_reset;
+ u8 m_lcd_mask;
+ u8 m_digit_idx;
+ u8 m_digit_data[4];
+
+ u8 m_kp_mux;
+ u8 m_cb_mux;
+ u8 m_led_data;
};
void mm1_state::machine_start()
{
+ // zerofill
+ m_reset = false;
+ m_lcd_mask = 0;
+ m_digit_idx = 0;
+ memset(m_digit_data, 0, sizeof(m_digit_data));
+
+ m_kp_mux = 0;
+ m_cb_mux = 0;
+ m_led_data = 0;
+
+ // register for savestates
+ save_item(NAME(m_reset));
+ save_item(NAME(m_lcd_mask));
+ save_item(NAME(m_digit_idx));
+ save_item(NAME(m_digit_data));
+
+ save_item(NAME(m_kp_mux));
+ save_item(NAME(m_cb_mux));
+ save_item(NAME(m_led_data));
+}
+
+void mm1_state::machine_reset()
+{
+ m_reset = true;
+ m_digit_idx = 0;
}
@@ -80,6 +128,98 @@ void mm1_state::machine_start()
I/O
******************************************************************************/
+INTERRUPT_GEN_MEMBER(mm1_state::interrupt)
+{
+ m_maincpu->set_input_line(COSMAC_INPUT_LINE_INT, HOLD_LINE);
+}
+
+READ_LINE_MEMBER(mm1_state::clear_r)
+{
+ // CLEAR low + RESET high resets cpu
+ int ret = (m_reset) ? 0 : 1;
+ m_reset = false;
+ return ret;
+}
+
+WRITE_LINE_MEMBER(mm1_state::q_w)
+{
+ // Q: LCD digit data mask
+ // also assume LCD update on rising edge
+ if (state && !m_lcd_mask)
+ {
+ for (int i = 0; i < 4; i++)
+ m_display->write_row(i, m_digit_data[i]);
+ m_display->update();
+ }
+
+ m_lcd_mask = state ? 0xff : 0;
+}
+
+WRITE8_MEMBER(mm1_state::lcd_w)
+{
+ // d0-d7: write/shift LCD digit (4*CD4015)
+ // note: last digit "dp" is the colon in the middle
+ m_digit_data[m_digit_idx] = data ^ m_lcd_mask;
+ m_digit_idx = (m_digit_idx + 1) & 3;
+}
+
+WRITE8_MEMBER(mm1_state::sound_w)
+{
+ // d0: speaker out
+ m_dac->write(~data & 1);
+}
+
+void mm1_state::update_display()
+{
+ // 64 chessboard leds
+ m_display->matrix_partial(4, 8, m_cb_mux, m_led_data);
+}
+
+WRITE8_MEMBER(mm1_state::led_w)
+{
+ // d0-d7: chessboard led data
+ m_led_data = data;
+ update_display();
+}
+
+WRITE8_MEMBER(mm1_state::board_w)
+{
+ // d0-d7: chessboard input/led mux
+ m_cb_mux = ~data;
+ update_display();
+}
+
+READ8_MEMBER(mm1_state::board_r)
+{
+ u8 data = 0;
+
+ // d0-d7: multiplexed inputs (chessboard)
+ for (int i = 0; i < 8; i++)
+ if (BIT(m_cb_mux, i))
+ data |= m_board->read_rank(i);
+
+ return ~data;
+}
+
+WRITE8_MEMBER(mm1_state::keypad_w)
+{
+ // d0-d7: keypad input mux
+ m_kp_mux = ~data;
+}
+
+template<int P>
+READ_LINE_MEMBER(mm1_state::keypad_r)
+{
+ u8 data = 0;
+
+ // EF3,EF4: multiplexed inputs (keypad)
+ for (int i = 0; i < 8; i++)
+ if (BIT(m_kp_mux, i))
+ data |= m_inputs[i]->read();
+
+ return data >> P & 1;
+}
+
/******************************************************************************
@@ -88,11 +228,18 @@ void mm1_state::machine_start()
void mm1_state::mm1_map(address_map &map)
{
- map(0x0000, 0x7fff).rom();
+ map(0x0000, 0x7fff).rom().nopw();
+ map(0xd000, 0xdfff).mirror(0x2000).ram();
}
void mm1_state::mm1_io(address_map &map)
{
+ map(0x01, 0x01).w(FUNC(mm1_state::sound_w));
+ map(0x02, 0x02).w(FUNC(mm1_state::keypad_w));
+ map(0x03, 0x03).r(FUNC(mm1_state::board_r));
+ map(0x04, 0x04).w(FUNC(mm1_state::board_w));
+ map(0x05, 0x05).w(FUNC(mm1_state::led_w));
+ map(0x06, 0x06).w(FUNC(mm1_state::lcd_w));
}
@@ -103,28 +250,36 @@ void mm1_state::mm1_io(address_map &map)
static INPUT_PORTS_START( mm1 )
PORT_START("IN.0")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1)
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2)
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3)
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4)
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) // e5
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) // 9?
PORT_START("IN.1")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5)
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6)
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7)
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8)
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) // info?
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) // cl?
PORT_START("IN.2")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q)
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W)
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E)
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R)
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) // 0?
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) // c3
PORT_START("IN.3")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T)
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y)
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U)
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I)
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) // pos?
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) // ent?
+
+ PORT_START("IN.4")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) // h8
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_W) // d4
+
+ PORT_START("IN.5")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_E) // lev?
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_R) // a1
+
+ PORT_START("IN.6")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_T) // g7
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) // f6
+
+ PORT_START("IN.7")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_U) // memo?
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_I) // b2
INPUT_PORTS_END
@@ -139,10 +294,16 @@ void mm1_state::mm1(machine_config &config)
CDP1802(config, m_maincpu, 8_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &mm1_state::mm1_map);
m_maincpu->set_addrmap(AS_IO, &mm1_state::mm1_io);
+ m_maincpu->clear_cb().set(FUNC(mm1_state::clear_r));
+ m_maincpu->q_cb().set(FUNC(mm1_state::q_w));
+ m_maincpu->ef3_cb().set(FUNC(mm1_state::keypad_r<0>));
+ m_maincpu->ef4_cb().set(FUNC(mm1_state::keypad_r<1>));
+
+ m_maincpu->set_periodic_int(FUNC(mm1_state::interrupt), attotime::from_hz(150)); // fake
SENSORBOARD(config, 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(250));
+ m_board->set_delay(attotime::from_msec(200));
/* video hardware */
PWM_DISPLAY(config, m_display).set_size(4+8, 8);