mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
microvsn: cleanup, Finish support for i8021 based cartridges (nw)
This commit is contained in:
parent
2add7c158c
commit
7f3cbeb198
@ -106,7 +106,7 @@ The "overlay" feature indicates screen/keypad overlay
|
||||
<info name="pcb" value="4952-79 REV-B" /> <!-- correct? -->
|
||||
<info name="serial" value="4971" />
|
||||
<part name="cart" interface="microvision_cart">
|
||||
<feature name="clock" value="500000" /> <!-- correct? -->
|
||||
<feature name="clock" value="500000" /> <!-- RC = 100pf/23.2K? (matches video recording) -->
|
||||
<feature name="pla" value="1" />
|
||||
<feature name="paddle" value="1" />
|
||||
<feature name="overlay" value="2" />
|
||||
@ -123,10 +123,10 @@ The "overlay" feature indicates screen/keypad overlay
|
||||
<info name="pcb" value="4971-REV-C" />
|
||||
<info name="serial" value="4971" />
|
||||
<part name="cart" interface="microvision_cart">
|
||||
<feature name="clock" value="2000000" /> <!-- LC circuit -->
|
||||
<feature name="clock" value="3500000" /> <!-- LC circuit, correct? (matches video recording) -->
|
||||
<feature name="paddle" value="1" />
|
||||
<feature name="overlay" value="2" />
|
||||
<dataarea name="rom" size="0x400"> <!-- I8021 MCU -->
|
||||
<dataarea name="rom" size="0x400"> <!-- Intel 8021 MCU -->
|
||||
<rom name="4971" size="0x400" crc="bdd8660b" sha1="971f9117dc809f7b9796134208b47ea34990ae71"/>
|
||||
</dataarea>
|
||||
</part>
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
TODO:
|
||||
- split driver into several files?
|
||||
- megaiv/smondial leds are tri-color
|
||||
- why are megaiv/smondial2 beeps noisy?
|
||||
- add Monte Carlo IV (non-LE)
|
||||
- add MM 1000 module
|
||||
|
@ -1,7 +1,7 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Wilbert Pol, hap
|
||||
// thanks-to:Dan Boris, Kevin Horton, Sean Riddle
|
||||
/***************************************************************************
|
||||
/******************************************************************************
|
||||
|
||||
Milton Bradley MicroVision, handheld game console
|
||||
|
||||
@ -11,21 +11,16 @@ Hardware notes:
|
||||
- no CPU on console, it is on the cartridge
|
||||
|
||||
12 games were released, all of them have a TMS1100 MCU. The first couple of
|
||||
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 350KHz.
|
||||
games had an Intel 8021 MCU at first, but Milton Bradley switched to TMS1100.
|
||||
|
||||
Each game had a screen- and keypad overlay attached to it, MAME external
|
||||
artwork is recommended. It's also advised to disable screen filtering,
|
||||
eg. with -prescale, or on Windows simply -video gdi.
|
||||
|
||||
TODO:
|
||||
- Finish support for i8021 based cartridges
|
||||
- dump/add remaining 8021 cartridges
|
||||
|
||||
****************************************************************************/
|
||||
******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
@ -33,6 +28,7 @@ TODO:
|
||||
#include "bus/generic/slot.h"
|
||||
#include "cpu/mcs48/mcs48.h"
|
||||
#include "cpu/tms1000/tms1100.h"
|
||||
#include "machine/timer.h"
|
||||
#include "sound/dac.h"
|
||||
#include "sound/volt_reg.h"
|
||||
#include "video/hlcd0488.h"
|
||||
@ -43,21 +39,21 @@ TODO:
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
//#define VERBOSE 1
|
||||
#include "logmacro.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class microvision_state : public driver_device
|
||||
{
|
||||
public:
|
||||
microvision_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_dac( *this, "dac" ),
|
||||
m_i8021( *this, "i8021_cpu" ),
|
||||
m_tms1100( *this, "tms1100_cpu" ),
|
||||
m_i8021( *this, "i8021_cpu" ),
|
||||
m_lcd(*this, "lcd"),
|
||||
m_lcd_pwm(*this, "lcd_pwm"),
|
||||
m_dac( *this, "dac" ),
|
||||
m_cart(*this, "cartslot"),
|
||||
m_paddle_timer(*this, "paddle_timer"),
|
||||
m_inputs(*this, "COL%u", 0),
|
||||
m_paddle(*this, "PADDLE"),
|
||||
m_conf(*this, "CONF"),
|
||||
@ -69,56 +65,25 @@ public:
|
||||
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;
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void device_post_load() override { apply_settings(); }
|
||||
|
||||
private:
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
|
||||
|
||||
// i8021 interface
|
||||
DECLARE_WRITE8_MEMBER(i8021_p0_write);
|
||||
DECLARE_WRITE8_MEMBER(i8021_p1_write);
|
||||
DECLARE_WRITE8_MEMBER(i8021_p2_write);
|
||||
DECLARE_READ_LINE_MEMBER(i8021_t1_read);
|
||||
DECLARE_READ8_MEMBER(i8021_bus_read);
|
||||
|
||||
// TMS1100 interface
|
||||
DECLARE_READ8_MEMBER(tms1100_read_k);
|
||||
DECLARE_WRITE16_MEMBER(tms1100_write_o);
|
||||
DECLARE_WRITE16_MEMBER(tms1100_write_r);
|
||||
u32 tms1100_decode_micro(offs_t offset);
|
||||
|
||||
required_device<dac_byte_interface> m_dac;
|
||||
optional_device<i8021_device> m_i8021;
|
||||
optional_device<tms1100_cpu_device> m_tms1100;
|
||||
optional_device<i8021_device> m_i8021;
|
||||
required_device<hlcd0488_device> m_lcd;
|
||||
required_device<pwm_display_device> m_lcd_pwm;
|
||||
required_device<dac_byte_interface> m_dac;
|
||||
required_device<generic_slot_device> m_cart;
|
||||
required_device<timer_device> m_paddle_timer;
|
||||
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;
|
||||
|
||||
// i8021 variables
|
||||
uint8_t m_p0;
|
||||
uint8_t m_p2;
|
||||
uint8_t m_t1;
|
||||
|
||||
// tms1100 variables
|
||||
uint16_t m_r;
|
||||
uint16_t m_o;
|
||||
|
||||
// generic variables
|
||||
DECLARE_WRITE16_MEMBER(lcd_output_w);
|
||||
|
||||
u32 tms1100_decode_micro(offs_t offset);
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
|
||||
void apply_settings(void);
|
||||
|
||||
u8 m_pla_auto;
|
||||
@ -126,238 +91,51 @@ private:
|
||||
u16 m_button_mask;
|
||||
bool m_paddle_auto;
|
||||
bool m_paddle_on;
|
||||
};
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE16_MEMBER(lcd_output_w) { m_lcd_pwm->matrix(offset, data); }
|
||||
|
||||
// TMS1100 interface
|
||||
DECLARE_READ8_MEMBER(tms1100_k_r);
|
||||
DECLARE_WRITE16_MEMBER(tms1100_o_w);
|
||||
DECLARE_WRITE16_MEMBER(tms1100_r_w);
|
||||
|
||||
u16 m_r = 0;
|
||||
|
||||
// Intel 8021 interface
|
||||
DECLARE_READ8_MEMBER(i8021_p0_r);
|
||||
DECLARE_WRITE8_MEMBER(i8021_p0_w);
|
||||
DECLARE_WRITE8_MEMBER(i8021_p1_w);
|
||||
DECLARE_WRITE8_MEMBER(i8021_p2_w);
|
||||
DECLARE_READ_LINE_MEMBER(i8021_t1_r);
|
||||
|
||||
u8 m_p0 = 0xff;
|
||||
u8 m_p2 = 0xff;
|
||||
};
|
||||
|
||||
void microvision_state::machine_start()
|
||||
{
|
||||
m_paddle_timer = timer_alloc(TIMER_PADDLE);
|
||||
m_overlay_out.resolve();
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_r));
|
||||
save_item(NAME(m_p0));
|
||||
save_item(NAME(m_p2));
|
||||
save_item(NAME(m_t1));
|
||||
save_item(NAME(m_r));
|
||||
save_item(NAME(m_o));
|
||||
}
|
||||
|
||||
// don't save: m_pla_auto, m_overlay_auto, m_paddle_auto,
|
||||
// m_button_mask, m_paddle_on
|
||||
}
|
||||
|
||||
void microvision_state::machine_reset()
|
||||
{
|
||||
apply_settings();
|
||||
|
||||
m_o = 0;
|
||||
m_r = 0;
|
||||
m_p0 = 0;
|
||||
m_p2 = 0;
|
||||
m_t1 = 0;
|
||||
|
||||
m_paddle_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t microvision_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
// simulate LCD persistence
|
||||
int p = m_lcd_pwm->read_element_bri(y ^ 15, x ^ 15) * 25000;
|
||||
p = (p > 255) ? 0 : p ^ 255;
|
||||
|
||||
bitmap.pix32(y, x) = p << 16 | p << 8 | p;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WRITE16_MEMBER( microvision_state::lcd_output_w )
|
||||
{
|
||||
m_lcd_pwm->matrix(offset, data);
|
||||
}
|
||||
|
||||
|
||||
void microvision_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch ( id )
|
||||
{
|
||||
case TIMER_PADDLE:
|
||||
m_t1 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
x--- ---- KEY3
|
||||
-x-- ---- KEY4
|
||||
--x- ---- KEY5
|
||||
---x ---- KEY6
|
||||
---- x---
|
||||
---- -x-- KEY0
|
||||
---- --x- KEY1
|
||||
---- ---x KEY2
|
||||
*/
|
||||
WRITE8_MEMBER( microvision_state::i8021_p0_write )
|
||||
{
|
||||
LOG( "p0_write: %02x\n", data );
|
||||
|
||||
m_p0 = data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
x--- ---- LCD3
|
||||
-x-- ---- LCD2
|
||||
--x- ---- LCD1
|
||||
---x ---- LCD0
|
||||
---- --x- LCD5
|
||||
---- ---x LCD4
|
||||
*/
|
||||
WRITE8_MEMBER( microvision_state::i8021_p1_write )
|
||||
{
|
||||
LOG( "p1_write: %02x\n", data );
|
||||
|
||||
m_lcd->data_w(data >> 4 & 0xf);
|
||||
m_lcd->latch_pulse_w(BIT(data, 0));
|
||||
m_lcd->data_clk_w(BIT(data, 1));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
---- xx-- CAP2 (paddle)
|
||||
---- --x- SPKR1
|
||||
---- ---x SPKR0
|
||||
*/
|
||||
WRITE8_MEMBER( microvision_state::i8021_p2_write )
|
||||
{
|
||||
LOG( "p2_write: %02x\n", data );
|
||||
|
||||
m_p2 = data;
|
||||
|
||||
m_dac->write(m_p2 & 0x03);
|
||||
|
||||
if ( m_p2 & 0x0c )
|
||||
{
|
||||
m_t1 = 1;
|
||||
// Stop paddle timer
|
||||
m_paddle_timer->adjust( attotime::never );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start paddle timer (min is 160uS, max is 678uS)
|
||||
uint8_t paddle = 255 - ioport("PADDLE")->read();
|
||||
m_paddle_timer->adjust( attotime::from_usec(160 + ( 518 * paddle ) / 255 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
READ_LINE_MEMBER( microvision_state::i8021_t1_read )
|
||||
{
|
||||
return m_t1;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER( microvision_state::i8021_bus_read )
|
||||
{
|
||||
uint8_t data = m_p0;
|
||||
|
||||
uint8_t col0 = ioport("COL0")->read();
|
||||
uint8_t col1 = ioport("COL1")->read();
|
||||
uint8_t col2 = ioport("COL2")->read();
|
||||
|
||||
// Row scanning
|
||||
if ( ! ( m_p0 & 0x80 ) )
|
||||
{
|
||||
uint8_t t = ( ( col0 & 0x01 ) << 2 ) | ( ( col1 & 0x01 ) << 1 ) | ( col2 & 0x01 );
|
||||
|
||||
data &= ( t ^ 0xFF );
|
||||
}
|
||||
if ( ! ( m_p0 & 0x40 ) )
|
||||
{
|
||||
uint8_t t = ( ( col0 & 0x02 ) << 1 ) | ( col1 & 0x02 ) | ( ( col2 & 0x02 ) >> 1 );
|
||||
|
||||
data &= ( t ^ 0xFF );
|
||||
}
|
||||
if ( ! ( m_p0 & 0x20 ) )
|
||||
{
|
||||
uint8_t t = ( col0 & 0x04 ) | ( ( col1 & 0x04 ) >> 1 ) | ( ( col2 & 0x04 ) >> 2 );
|
||||
|
||||
data &= ( t ^ 0xFF );
|
||||
}
|
||||
if ( ! ( m_p0 & 0x10 ) )
|
||||
{
|
||||
uint8_t t = ( ( col0 & 0x08 ) >> 1 ) | ( ( col1 & 0x08 ) >> 2 ) | ( ( col2 & 0x08 ) >> 3 );
|
||||
|
||||
data &= ( t ^ 0xFF );
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER( microvision_state::tms1100_read_k )
|
||||
{
|
||||
uint8_t data = 0;
|
||||
|
||||
LOG("read_k\n");
|
||||
|
||||
// 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)
|
||||
{
|
||||
u8 paddle = m_paddle_timer->enabled() ? 0 : BIT(m_r, 2);
|
||||
return paddle << 3 | data;
|
||||
}
|
||||
else
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
WRITE16_MEMBER( microvision_state::tms1100_write_o )
|
||||
{
|
||||
LOG("write_o: %04x\n", data);
|
||||
|
||||
// O0-O3: LCD data
|
||||
m_lcd->data_w(data & 0xf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
WRITE16_MEMBER( microvision_state::tms1100_write_r )
|
||||
{
|
||||
LOG("write_r: %04x\n", 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 = (2000 - 500) / 255.0; // approximate it
|
||||
m_paddle_timer->adjust(attotime::from_usec(500 + m_paddle->read() * step));
|
||||
}
|
||||
|
||||
// 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
|
||||
m_lcd->latch_pulse_w(BIT(data, 6));
|
||||
m_lcd->data_clk_w(BIT(data, 7));
|
||||
|
||||
// R8-R10: input mux
|
||||
m_r = data;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Cartridge Init
|
||||
******************************************************************************/
|
||||
|
||||
static const u16 microvision_output_pla[2][0x20] =
|
||||
{
|
||||
@ -424,7 +202,7 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state::cart_load)
|
||||
m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom");
|
||||
|
||||
// set default settings
|
||||
u32 clock = (size == 0x400) ? 2000000 : 500000;
|
||||
u32 clock = (size == 0x400) ? 3500000 : 500000;
|
||||
m_pla_auto = 0;
|
||||
m_overlay_auto = 0;
|
||||
m_paddle_auto = false;
|
||||
@ -467,8 +245,31 @@ void microvision_state::apply_settings()
|
||||
// overlay physically restricts button panel
|
||||
switch (overlay)
|
||||
{
|
||||
case 1: case 5:
|
||||
m_button_mask = 0x454;
|
||||
break;
|
||||
case 2: case 8: case 10:
|
||||
m_button_mask = 0x555;
|
||||
break;
|
||||
case 3:
|
||||
m_button_mask = 0x858;
|
||||
break;
|
||||
case 4:
|
||||
m_button_mask = 0xaea;
|
||||
break;
|
||||
case 6:
|
||||
m_button_mask = 0xaaa;
|
||||
break;
|
||||
case 11:
|
||||
m_button_mask = 0xafa;
|
||||
break;
|
||||
case 12:
|
||||
m_button_mask = 0x404;
|
||||
break;
|
||||
|
||||
default:
|
||||
m_button_mask = 0xfff;
|
||||
break;
|
||||
}
|
||||
|
||||
u8 pla = ((conf & 0x18) == 0x10) ? m_pla_auto : (conf >> 3 & 1);
|
||||
@ -478,6 +279,155 @@ void microvision_state::apply_settings()
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Video
|
||||
******************************************************************************/
|
||||
|
||||
uint32_t microvision_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
for (int y = 0; y < 16; y++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
// simulate LCD persistence
|
||||
int p = m_lcd_pwm->read_element_bri(y ^ 15, x ^ 15) * 25000;
|
||||
p = (p > 255) ? 0 : p ^ 255;
|
||||
|
||||
bitmap.pix32(y, x) = p << 16 | p << 8 | p;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
I/O
|
||||
******************************************************************************/
|
||||
|
||||
// TMS1100 interface
|
||||
|
||||
READ8_MEMBER(microvision_state::tms1100_k_r)
|
||||
{
|
||||
u8 data = 0;
|
||||
|
||||
// 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)
|
||||
{
|
||||
u8 paddle = m_paddle_timer->enabled() ? 0 : BIT(m_r, 2);
|
||||
return paddle << 3 | data;
|
||||
}
|
||||
else
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(microvision_state::tms1100_o_w)
|
||||
{
|
||||
// O0-O3: LCD data
|
||||
m_lcd->data_w(data & 0xf);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(microvision_state::tms1100_r_w)
|
||||
{
|
||||
// R2: charge paddle capacitor when high
|
||||
if (~m_r & data & 4 && m_paddle_on)
|
||||
{
|
||||
// note that the games don't use the whole range, so there's a deadzone around the edges
|
||||
const float step = (2000 - 500) / 255.0; // approximation
|
||||
m_paddle_timer->adjust(attotime::from_usec(500 + m_paddle->read() * step));
|
||||
}
|
||||
|
||||
// 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
|
||||
m_lcd->latch_pulse_w(BIT(data, 6));
|
||||
m_lcd->data_clk_w(BIT(data, 7));
|
||||
|
||||
// R8-R10: input mux
|
||||
m_r = data;
|
||||
}
|
||||
|
||||
|
||||
// Intel 8021 interface
|
||||
|
||||
READ8_MEMBER( microvision_state::i8021_p0_r )
|
||||
{
|
||||
u8 in[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
in[i] = m_inputs[i]->read() & (m_button_mask >> (i * 4) & 0xf);
|
||||
|
||||
u8 data = 0;
|
||||
|
||||
// P00-P02: multiplexed inputs from P04-P07
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (~(m_p0 >> 4) & in[i])
|
||||
data |= 1 << i;
|
||||
|
||||
// P04-P07: multiplexed inputs from P00-P02
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (BIT(~m_p0, i))
|
||||
data |= in[i] << 4;
|
||||
|
||||
return ~data & m_p0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(microvision_state::i8021_p0_w)
|
||||
{
|
||||
// P0-P2, P4-P7: input mux
|
||||
m_p0 = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(microvision_state::i8021_p1_w)
|
||||
{
|
||||
// P14-P17: lcd data
|
||||
m_lcd->data_w(data >> 4 & 0xf);
|
||||
|
||||
// P10: lcd latch pulse
|
||||
// P11: lcd data clk
|
||||
m_lcd->latch_pulse_w(BIT(data, 0));
|
||||
m_lcd->data_clk_w(BIT(data, 1));
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(microvision_state::i8021_p2_w)
|
||||
{
|
||||
// P20: speaker lead 1
|
||||
// P21: speaker lead 2
|
||||
m_dac->write(data & 3);
|
||||
|
||||
// P22,P23: charge paddle capacitor when low
|
||||
if (m_p2 & 0xc && (data & 0xc) == 0 && m_paddle_on)
|
||||
{
|
||||
const float step = (1000 - 10) / 255.0; // approximation
|
||||
m_paddle_timer->adjust(attotime::from_usec(10 + (m_paddle->read() ^ 0xff) * step));
|
||||
}
|
||||
|
||||
m_p2 = data;
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(microvision_state::i8021_t1_r)
|
||||
{
|
||||
// T1: paddle capacitor (active low)
|
||||
int active = (m_p2 & 0xc) ? 1 : 0;
|
||||
active |= m_paddle_timer->enabled() ? 1 : 0;
|
||||
return (m_paddle_on) ? active : 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Input Ports
|
||||
******************************************************************************/
|
||||
|
||||
static INPUT_PORTS_START( microvision )
|
||||
PORT_START("COL0")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON12 ) PORT_CODE(KEYCODE_C)
|
||||
@ -515,22 +465,29 @@ static INPUT_PORTS_START( microvision )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Machine Configs
|
||||
******************************************************************************/
|
||||
|
||||
void microvision_state::microvision(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
I8021(config, m_i8021, 0);
|
||||
m_i8021->bus_out_cb().set(FUNC(microvision_state::i8021_p0_write));
|
||||
m_i8021->p1_out_cb().set(FUNC(microvision_state::i8021_p1_write));
|
||||
m_i8021->p2_out_cb().set(FUNC(microvision_state::i8021_p2_write));
|
||||
m_i8021->t1_in_cb().set(FUNC(microvision_state::i8021_t1_read));
|
||||
m_i8021->bus_in_cb().set(FUNC(microvision_state::i8021_bus_read));
|
||||
|
||||
TMS1100(config, m_tms1100, 0);
|
||||
m_tms1100->set_output_pla(microvision_output_pla[0]);
|
||||
m_tms1100->set_decode_micro().set(FUNC(microvision_state::tms1100_decode_micro));
|
||||
m_tms1100->k().set(FUNC(microvision_state::tms1100_read_k));
|
||||
m_tms1100->o().set(FUNC(microvision_state::tms1100_write_o));
|
||||
m_tms1100->r().set(FUNC(microvision_state::tms1100_write_r));
|
||||
m_tms1100->k().set(FUNC(microvision_state::tms1100_k_r));
|
||||
m_tms1100->o().set(FUNC(microvision_state::tms1100_o_w));
|
||||
m_tms1100->r().set(FUNC(microvision_state::tms1100_r_w));
|
||||
|
||||
I8021(config, m_i8021, 0);
|
||||
m_i8021->bus_in_cb().set(FUNC(microvision_state::i8021_p0_r));
|
||||
m_i8021->bus_out_cb().set(FUNC(microvision_state::i8021_p0_w));
|
||||
m_i8021->p1_out_cb().set(FUNC(microvision_state::i8021_p1_w));
|
||||
m_i8021->p2_out_cb().set(FUNC(microvision_state::i8021_p2_w));
|
||||
m_i8021->t1_in_cb().set(FUNC(microvision_state::i8021_t1_r));
|
||||
|
||||
TIMER(config, "paddle_timer").configure_generic(nullptr);
|
||||
|
||||
/* video hardware */
|
||||
HLCD0488(config, m_lcd);
|
||||
@ -561,6 +518,11 @@ void microvision_state::microvision(machine_config &config)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
ROM Definitions
|
||||
******************************************************************************/
|
||||
|
||||
ROM_START( microvsn )
|
||||
// nothing here yet, ROM is on the cartridge
|
||||
ROM_REGION( 0x400, "i8021_cpu", ROMREGION_ERASE00 )
|
||||
@ -569,5 +531,13 @@ ROM_START( microvsn )
|
||||
ROM_REGION( 365, "tms1100_cpu:opla", ROMREGION_ERASE00 )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
CONS( 1979, microvsn, 0, 0, microvision, microvision, microvision_state, empty_init, "Milton Bradley", "MicroVision", MACHINE_NOT_WORKING | MACHINE_REQUIRES_ARTWORK )
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
Drivers
|
||||
******************************************************************************/
|
||||
|
||||
// YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
|
||||
CONS( 1979, microvsn, 0, 0, microvision, microvision, microvision_state, empty_init, "Milton Bradley", "MicroVision", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK )
|
||||
|
@ -1,7 +1,7 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:hap
|
||||
// thanks-to:Kevin Horton, Sean Riddle
|
||||
/***************************************************************************
|
||||
/******************************************************************************
|
||||
|
||||
Entex Select-A-Game Machine, handheld game console.
|
||||
Technically, the main unit is the peripheral(buttons, display, speaker, power),
|
||||
@ -32,7 +32,7 @@ are played, Space Invader 2 is an exception.
|
||||
TODO:
|
||||
- add the rest of the games
|
||||
|
||||
***************************************************************************/
|
||||
******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user