summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--hash/microvision.xml8
-rw-r--r--src/mame/drivers/hh_hmcs40.cpp3
-rw-r--r--src/mame/drivers/microvsn.cpp141
3 files changed, 105 insertions, 47 deletions
diff --git a/hash/microvision.xml b/hash/microvision.xml
index 9802287f40b..a408cfd30ed 100644
--- a/hash/microvision.xml
+++ b/hash/microvision.xml
@@ -52,7 +52,7 @@ The "overlay" feature indicates screen/keypad overlay
<description>Baseball</description>
<year>1980</year>
<publisher>Milton Bradley</publisher>
- <info name="pcb" value="4952-79 REV-B" />
+ <info name="pcb" value="4952-79 REV-B" /> <!-- also seen with 4952-56 REV- -->
<info name="serial" value="4063" />
<part name="cart" interface="microvision_cart">
<feature name="clock" value="500000" /> <!-- RC = 100pf/23.2K -->
@@ -187,7 +187,7 @@ The "overlay" feature indicates screen/keypad overlay
<description>Pinball</description>
<year>1979</year>
<publisher>Milton Bradley</publisher>
- <info name="pcb" value="4952-79 REV-B" />
+ <info name="pcb" value="4952-79 REV-B" /> <!-- also seen with 4952 REV-A -->
<info name="serial" value="4974" />
<part name="cart" interface="microvision_cart">
<feature name="clock" value="550000" /> <!-- RC = 100pf/21.0K -->
@@ -207,7 +207,7 @@ The "overlay" feature indicates screen/keypad overlay
<info name="pcb" value="4952-79 REV-B" />
<info name="serial" value="4064" />
<part name="cart" interface="microvision_cart">
- <feature name="clock" value="300000" /> <!-- RC = 100pf/39.4K -->
+ <feature name="clock" value="350000" /> <!-- RC = 100pf/39.4K -->
<feature name="pla" value="1" />
<feature name="paddle" value="0" />
<feature name="overlay" value="9" />
@@ -252,7 +252,7 @@ The "overlay" feature indicates screen/keypad overlay
</software>
-<!-- Homebrew (emulator-only, untested on real console) -->
+<!-- Homebrew (emulator or Arduino version, untested on real console) -->
<software name="bomber">
<description>Bomber</description>
diff --git a/src/mame/drivers/hh_hmcs40.cpp b/src/mame/drivers/hh_hmcs40.cpp
index cf1d5d91b88..b0ac521b661 100644
--- a/src/mame/drivers/hh_hmcs40.cpp
+++ b/src/mame/drivers/hh_hmcs40.cpp
@@ -60,12 +60,13 @@
@A88 HD38820 1984, Bandai Pair Match (PT-460) (1/2)
@A89 HD38820 1984, Bandai Pair Match (PT-460) (2/2)
+ *A50 HD44801 1981, CXG Sensor Computachess
A75 HD44801 1982, Alpha 8201 protection MCU -> machine/alpha8201.*
B35 HD44801 1983, Alpha 8302 protection MCU (see 8201)
B42 HD44801 1983, Alpha 8303 protection MCU (see 8201)
*B43 HD44801 1983, Alpha 8304 protection MCU (see 8201)
C57 HD44801 1985, Alpha 8505 protection MCU (see 8201)
- *C89 HD44801 1986, CXG Computachess IV
+ *C89 HD44801 1985, CXG Portachess II / Computachess IV
*A14 HD44840 1982, CXG Advanced Portachess
diff --git a/src/mame/drivers/microvsn.cpp b/src/mame/drivers/microvsn.cpp
index 62dc5fce08e..04cbafacbc2 100644
--- a/src/mame/drivers/microvsn.cpp
+++ b/src/mame/drivers/microvsn.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Wilbert Pol
+// copyright-holders:Wilbert Pol, hap
// thanks-to:Kevin Horton, Sean Riddle
/***************************************************************************
@@ -16,12 +16,12 @@ games had an I8021 MCU at first, but Milton Bradley switched to TMS1100.
Since the microcontrollers were on the cartridges it was possible to have
different clocks on different games.
The Connect Four I8021 game is clocked at around 2MHz. The TMS1100 versions
-of the games were clocked at around 500KHz, 550KHz, or 300KHz.
+of the games were clocked at around 500KHz, 550KHz, or 350KHz.
-Each game came with a screen- and keypad overlay, MAME artwork is recommended.
+Each game had a screen- and keypad overlay attached to it, MAME external
+artwork is recommended.
TODO:
-- Add support for the paddle control
- Finish support for i8021 based cartridges
****************************************************************************/
@@ -54,11 +54,17 @@ public:
m_dac( *this, "dac" ),
m_i8021( *this, "i8021_cpu" ),
m_tms1100( *this, "tms1100_cpu" ),
- m_cart(*this, "cartslot")
+ m_cart(*this, "cartslot"),
+ m_inputs(*this, "COL%u", 0),
+ m_paddle(*this, "PADDLE"),
+ m_conf(*this, "CONF"),
+ m_overlay_out(*this, "overlay")
{ }
void microvision(machine_config &config);
+ DECLARE_INPUT_CHANGED_MEMBER(conf_changed) { apply_settings(); }
+
protected:
static constexpr device_timer_id TIMER_PADDLE = 0;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
@@ -91,6 +97,10 @@ private:
optional_device<i8021_device> m_i8021;
optional_device<tms1100_cpu_device> m_tms1100;
required_device<generic_slot_device> m_cart;
+ required_ioport_array<3> m_inputs;
+ required_ioport m_paddle;
+ required_ioport m_conf;
+ output_finder<> m_overlay_out;
// Timers
emu_timer *m_paddle_timer;
@@ -107,9 +117,14 @@ private:
// generic variables
void update_lcd();
void lcd_write(uint8_t control, uint8_t data);
+
+ void apply_settings(void);
+
u8 m_pla_auto;
u8 m_overlay_auto;
+ u16 m_button_mask;
bool m_paddle_auto;
+ bool m_paddle_on;
uint8_t m_lcd_latch[8];
uint8_t m_lcd_holding_latch[8];
@@ -143,6 +158,7 @@ void microvision_state::microvision_palette(palette_device &palette) const
void microvision_state::machine_start()
{
m_paddle_timer = timer_alloc(TIMER_PADDLE);
+ m_overlay_out.resolve();
save_item(NAME(m_p0));
save_item(NAME(m_p2));
@@ -159,6 +175,7 @@ void microvision_state::machine_start()
void microvision_state::machine_reset()
{
+ apply_settings();
std::fill(std::begin(m_lcd_latch), std::end(m_lcd_latch), 0);
for (auto &elem : m_lcd)
@@ -395,19 +412,19 @@ READ8_MEMBER( microvision_state::tms1100_read_k )
LOG("read_k\n");
- if ( m_r & 0x100 )
- {
- data |= ioport("COL0")->read();
- }
- if ( m_r & 0x200 )
- {
- data |= ioport("COL1")->read();
- }
- if ( m_r & 0x400 )
+ // multiplexed inputs
+ for (int i = 0; i < 3; i++)
+ if (BIT(m_r, i + 8))
+ data |= m_inputs[i]->read() & (m_button_mask >> (i * 4) & 0xf);
+
+ // K8: paddle capacitor
+ if (m_paddle_on)
{
- data |= ioport("COL2")->read();
+ u8 paddle = m_paddle_timer->enabled() ? 0 : BIT(m_r, 2);
+ return paddle << 3 | data;
}
- return data;
+ else
+ return data;
}
@@ -415,29 +432,37 @@ WRITE16_MEMBER( microvision_state::tms1100_write_o )
{
LOG("write_o: %04x\n", data);
+ // O0-O3: LCD data
m_o = data;
lcd_write( ( m_r >> 6 ) & 0x03, m_o & 0x0f );
}
-/*
-x-- ---- ---- KEY2
--x- ---- ---- KEY1
---x ---- ---- KEY0
---- x--- ---- LCD5
---- -x-- ---- LCD4
---- ---- --x- SPKR0
---- ---- ---x SPKR1
-*/
+
WRITE16_MEMBER( microvision_state::tms1100_write_r )
{
LOG("write_r: %04x\n", data);
- m_r = data;
+ // R2: charge paddle capacitor
+ if (~m_r & data & 4 && m_paddle_on)
+ {
+ // range is ~360us to ~2663us (measured on 4952-79 REV B PCB)
+ // note that the games don't use the whole range, so there's a deadzone around the edges
+ float step = (2663 - 360) / 255.0;
+ m_paddle_timer->adjust(attotime::from_usec(360 + m_paddle->read() * step));
+ }
- m_dac->write((BIT(m_r, 0) << 1) | BIT(m_r, 1));
- lcd_write( ( m_r >> 6 ) & 0x03, m_o & 0x0f );
+ // R0: speaker lead 2
+ // R1: speaker lead 1 (GND on some carts)
+ m_dac->write((BIT(data, 0) << 1) | BIT(data, 1));
+
+ // R6: LCD latch pulse
+ // R7: LCD data clock
+ lcd_write((data >> 6) & 0x03, m_o & 0x0f);
+
+ // R8-R10: input mux
+ m_r = data;
}
@@ -534,34 +559,66 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state::cart_load)
// TMS1100 MCU
memcpy(memregion("tms1100_cpu")->base(), m_cart->get_rom_base(), size);
m_tms1100->set_clock(clock);
- m_tms1100->set_output_pla(microvision_output_pla[m_pla_auto]);
}
return image_init_result::PASS;
}
+void microvision_state::apply_settings()
+{
+ u8 conf = m_conf->read();
+
+ u8 overlay = (conf & 1) ? m_overlay_auto : 0;
+ m_overlay_out = overlay;
+
+ // overlay physically restricts button panel
+ switch (overlay)
+ {
+ default:
+ m_button_mask = 0xfff;
+ }
+
+ u8 pla = ((conf & 0x18) == 0x10) ? m_pla_auto : (conf >> 3 & 1);
+ m_tms1100->set_output_pla(microvision_output_pla[pla]);
+
+ m_paddle_on = ((conf & 6) == 4) ? m_paddle_auto : bool(conf & 2);
+}
+
static INPUT_PORTS_START( microvision )
PORT_START("COL0")
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_CODE(KEYCODE_3) PORT_NAME("B01")
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_CODE(KEYCODE_E) PORT_NAME("B04")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_CODE(KEYCODE_D) PORT_NAME("B07")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON10) PORT_CODE(KEYCODE_C) PORT_NAME("B10")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON12 ) PORT_CODE(KEYCODE_C)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_CODE(KEYCODE_D)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_CODE(KEYCODE_E)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CODE(KEYCODE_3)
PORT_START("COL1")
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_CODE(KEYCODE_4) PORT_NAME("B02")
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_CODE(KEYCODE_R) PORT_NAME("B05")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_CODE(KEYCODE_F) PORT_NAME("B08")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON11) PORT_CODE(KEYCODE_V) PORT_NAME("B11")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_CODE(KEYCODE_X)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_CODE(KEYCODE_S)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CODE(KEYCODE_W)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CODE(KEYCODE_2)
PORT_START("COL2")
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CODE(KEYCODE_5) PORT_NAME("B03")
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_CODE(KEYCODE_T) PORT_NAME("B06")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON9) PORT_CODE(KEYCODE_G) PORT_NAME("B09")
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON12) PORT_CODE(KEYCODE_B) PORT_NAME("B12")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON10 ) PORT_CODE(KEYCODE_Z)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_CODE(KEYCODE_A)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CODE(KEYCODE_Q)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CODE(KEYCODE_1)
PORT_START("PADDLE")
- PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_PLAYER(1) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_MINMAX(0, 255)
+ PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_SENSITIVITY(15) PORT_KEYDELTA(15) PORT_CENTERDELTA(0)
+
+ PORT_START("CONF")
+ PORT_CONFNAME( 0x01, 0x01, "Overlay" ) PORT_CHANGED_MEMBER(DEVICE_SELF, microvision_state, conf_changed, 0)
+ PORT_CONFSETTING( 0x00, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x01, "Auto" )
+ PORT_CONFNAME( 0x06, 0x04, "Paddle Hardware" ) PORT_CHANGED_MEMBER(DEVICE_SELF, microvision_state, conf_changed, 0)
+ PORT_CONFSETTING( 0x00, DEF_STR( No ) ) // no circuitry on cartridge PCB
+ PORT_CONFSETTING( 0x02, DEF_STR( Yes ) )
+ PORT_CONFSETTING( 0x04, "Auto" )
+ PORT_CONFNAME( 0x18, 0x10, "TMS1100 PLA" ) PORT_CHANGED_MEMBER(DEVICE_SELF, microvision_state, conf_changed, 0)
+ PORT_CONFSETTING( 0x00, "0" )
+ PORT_CONFSETTING( 0x08, "1" )
+ PORT_CONFSETTING( 0x10, "Auto" )
INPUT_PORTS_END