mirror of
https://github.com/holub/mame
synced 2025-10-04 08:28:39 +03:00
tb303, tr606: disconnect from hh_ucom4 (nw)
This commit is contained in:
parent
e979607ad8
commit
b9bc5cf151
@ -2705,9 +2705,6 @@ createMESSProjects(_target, _subtarget, "nec")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/drivers/apc.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/hh_ucom4.cpp",
|
||||
MAME_DIR .. "src/mame/includes/hh_ucom4.h",
|
||||
MAME_DIR .. "src/mame/drivers/tb303.cpp", -- subdriver of hh_ucom4
|
||||
MAME_DIR .. "src/mame/drivers/tr606.cpp", -- "
|
||||
MAME_DIR .. "src/mame/drivers/pce.cpp",
|
||||
MAME_DIR .. "src/mame/includes/pce.h",
|
||||
MAME_DIR .. "src/mame/machine/pce.cpp",
|
||||
@ -3030,6 +3027,8 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/rmt32.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/rd110.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/rsc55.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/tb303.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/tr606.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "rolm")
|
||||
|
@ -5,9 +5,6 @@
|
||||
|
||||
NEC uCOM4 MCU tabletops/handhelds or other simple devices,
|
||||
most of them (emulated ones) are VFD electronic games/toys.
|
||||
List of child drivers:
|
||||
- tb303: Roland TB-303
|
||||
- tr606: Roland TR-606
|
||||
|
||||
Commonly used VFD(vacuum fluorescent display) are by NEC or Futaba.
|
||||
|
||||
@ -68,9 +65,10 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/hh_ucom4.h"
|
||||
|
||||
#include "cpu/ucom4/ucom4.h"
|
||||
#include "video/pwm.h"
|
||||
#include "video/hlcd0515.h"
|
||||
#include "sound/spkrdev.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
@ -88,6 +86,42 @@
|
||||
//#include "hh_ucom4_test.lh" // common test-layout - no svg artwork(yet), use external artwork
|
||||
|
||||
|
||||
class hh_ucom4_state : public driver_device
|
||||
{
|
||||
public:
|
||||
hh_ucom4_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_display(*this, "display"),
|
||||
m_speaker(*this, "speaker"),
|
||||
m_inputs(*this, "IN.%u", 0)
|
||||
{ }
|
||||
|
||||
// devices
|
||||
required_device<ucom4_cpu_device> m_maincpu;
|
||||
optional_device<pwm_display_device> m_display;
|
||||
optional_device<speaker_sound_device> m_speaker;
|
||||
optional_ioport_array<6> m_inputs; // max 6
|
||||
|
||||
// misc common
|
||||
u8 m_port[9]; // MCU port A-I write data (optional)
|
||||
u8 m_int; // MCU INT pin state
|
||||
u16 m_inp_mux; // multiplexed inputs mask
|
||||
|
||||
u32 m_grid; // VFD current row data
|
||||
u32 m_plate; // VFD current column data
|
||||
|
||||
u8 read_inputs(int columns);
|
||||
void refresh_interrupts(void);
|
||||
void set_interrupt(int state);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
};
|
||||
|
||||
|
||||
// machine start/reset
|
||||
|
||||
void hh_ucom4_state::machine_start()
|
||||
|
@ -2,8 +2,6 @@
|
||||
// copyright-holders:hap
|
||||
/***************************************************************************
|
||||
|
||||
** subclass of hh_ucom4_state (includes/hh_ucom4.h, drivers/hh_ucom4.cpp) **
|
||||
|
||||
Roland TB-303 Bass Line, 1982, designed by Tadao Kikumoto
|
||||
* NEC uCOM-43 MCU, labeled D650C 133
|
||||
* 3*uPD444C 1024x4 Static CMOS SRAM
|
||||
@ -15,43 +13,80 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/hh_ucom4.h"
|
||||
|
||||
#include "cpu/ucom4/ucom4.h"
|
||||
#include "video/pwm.h"
|
||||
#include "machine/timer.h"
|
||||
|
||||
#include "tb303.lh"
|
||||
|
||||
|
||||
class tb303_state : public hh_ucom4_state
|
||||
class tb303_state : public driver_device
|
||||
{
|
||||
public:
|
||||
tb303_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
hh_ucom4_state(mconfig, type, tag)
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_display(*this, "display"),
|
||||
m_inputs(*this, "IN.%u", 0)
|
||||
{ }
|
||||
|
||||
void tb303(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
required_device<ucom4_cpu_device> m_maincpu;
|
||||
required_device<pwm_display_device> m_display;
|
||||
required_ioport_array<5> m_inputs;
|
||||
|
||||
u8 m_ram[0xc00];
|
||||
u8 m_ram_addrset[3];
|
||||
u16 m_ram_address;
|
||||
u8 m_ram_data;
|
||||
bool m_ram_ce;
|
||||
bool m_ram_we;
|
||||
u8 m_led_data;
|
||||
u8 m_inp_mux;
|
||||
|
||||
DECLARE_WRITE8_MEMBER(ram_w);
|
||||
DECLARE_READ8_MEMBER(ram_r);
|
||||
DECLARE_WRITE8_MEMBER(strobe_w);
|
||||
void refresh_ram();
|
||||
template<int N> DECLARE_WRITE8_MEMBER(ram_address_w);
|
||||
DECLARE_WRITE8_MEMBER(ram_data_w);
|
||||
DECLARE_READ8_MEMBER(ram_data_r);
|
||||
DECLARE_WRITE8_MEMBER(strobe_w);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(switch_w);
|
||||
DECLARE_READ8_MEMBER(input_r);
|
||||
void update_leds();
|
||||
DECLARE_WRITE8_MEMBER(led_w);
|
||||
DECLARE_WRITE8_MEMBER(input_w);
|
||||
DECLARE_READ8_MEMBER(input_r);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(tp3_clock) { m_maincpu->set_input_line(0, ASSERT_LINE); }
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(tp3_clear) { m_maincpu->set_input_line(0, CLEAR_LINE); }
|
||||
|
||||
virtual void machine_start() override;
|
||||
};
|
||||
|
||||
void tb303_state::machine_start()
|
||||
{
|
||||
// zerofill
|
||||
memset(m_ram, 0, sizeof(m_ram));
|
||||
memset(m_ram_addrset, 0, sizeof(m_ram_addrset));
|
||||
m_ram_address = 0;
|
||||
m_ram_data = 0;
|
||||
m_ram_ce = false;
|
||||
m_ram_we = false;
|
||||
m_led_data = 0;
|
||||
m_inp_mux = 0;
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_ram));
|
||||
save_item(NAME(m_ram_addrset));
|
||||
save_item(NAME(m_ram_address));
|
||||
save_item(NAME(m_ram_data));
|
||||
save_item(NAME(m_ram_ce));
|
||||
save_item(NAME(m_ram_we));
|
||||
save_item(NAME(m_led_data));
|
||||
save_item(NAME(m_inp_mux));
|
||||
}
|
||||
|
||||
// TP2 to MCU CLK: LC circuit(TI S74230), stable sine wave, 2.2us interval
|
||||
#define TP2_HZ 454545
|
||||
|
||||
@ -74,7 +109,7 @@ void tb303_state::refresh_ram()
|
||||
// _Q0: N/C, _Q1: IC-5, _Q2: IC-3, _Q3: IC-4
|
||||
m_ram_ce = true;
|
||||
u8 hi = 0;
|
||||
switch (m_port[NEC_UCOM4_PORTE] >> 2 & 3)
|
||||
switch (m_ram_addrset[2] >> 2 & 3)
|
||||
{
|
||||
case 0: m_ram_ce = false; break;
|
||||
case 1: hi = 0; break;
|
||||
@ -86,24 +121,31 @@ void tb303_state::refresh_ram()
|
||||
{
|
||||
// _WE must be high(read mode) for address transitions
|
||||
if (!m_ram_we)
|
||||
m_ram_address = hi << 10 | (m_port[NEC_UCOM4_PORTE] << 8 & 0x300) | m_port[NEC_UCOM4_PORTF] << 4 | m_port[NEC_UCOM4_PORTD];
|
||||
m_ram_address = hi << 10 | (m_ram_addrset[2] << 8 & 0x300) | m_ram_addrset[1] << 4 | m_ram_addrset[0];
|
||||
else
|
||||
m_ram[m_ram_address] = m_port[NEC_UCOM4_PORTC];
|
||||
m_ram[m_ram_address] = m_ram_data;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(tb303_state::ram_w)
|
||||
template<int N>
|
||||
WRITE8_MEMBER(tb303_state::ram_address_w)
|
||||
{
|
||||
// MCU C: RAM data
|
||||
// MCU D,F,E: RAM address
|
||||
m_port[offset] = data;
|
||||
m_ram_addrset[N] = data;
|
||||
refresh_ram();
|
||||
|
||||
// MCU D,F01: pitch data
|
||||
//..
|
||||
}
|
||||
|
||||
READ8_MEMBER(tb303_state::ram_r)
|
||||
WRITE8_MEMBER(tb303_state::ram_data_w)
|
||||
{
|
||||
// MCU C: RAM data
|
||||
m_ram_data = data;
|
||||
refresh_ram();
|
||||
}
|
||||
|
||||
READ8_MEMBER(tb303_state::ram_data_r)
|
||||
{
|
||||
// MCU C: RAM data
|
||||
if (m_ram_ce && !m_ram_we)
|
||||
@ -120,8 +162,6 @@ WRITE8_MEMBER(tb303_state::strobe_w)
|
||||
|
||||
// MCU I1: pitch data latch strobe
|
||||
// MCU I2: gate signal
|
||||
|
||||
m_port[offset] = data;
|
||||
}
|
||||
|
||||
|
||||
@ -136,34 +176,47 @@ void tb303_state::update_leds()
|
||||
0.2 D208 1.2 D215 2.2 D220 3.2 D210
|
||||
0.3 D209 1.3 D216 2.3 D221 3.3 D212
|
||||
*/
|
||||
m_display->matrix(m_port[NEC_UCOM4_PORTH], m_port[NEC_UCOM4_PORTG]);
|
||||
m_display->matrix(m_inp_mux, m_led_data);
|
||||
|
||||
// todo: battery led
|
||||
// todo: 4 more leds(see top-left part)
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(tb303_state::switch_w)
|
||||
WRITE8_MEMBER(tb303_state::led_w)
|
||||
{
|
||||
// MCU G: leds state
|
||||
// MCU H: input/led mux
|
||||
if (offset == NEC_UCOM4_PORTH)
|
||||
m_inp_mux = data = data ^ 0xf;
|
||||
m_led_data = data;
|
||||
update_leds();
|
||||
}
|
||||
|
||||
m_port[offset] = data;
|
||||
WRITE8_MEMBER(tb303_state::input_w)
|
||||
{
|
||||
// MCU H: input/led mux
|
||||
m_inp_mux = data ^ 0xf;
|
||||
update_leds();
|
||||
}
|
||||
|
||||
READ8_MEMBER(tb303_state::input_r)
|
||||
{
|
||||
u8 data = 0;
|
||||
|
||||
// MCU A,B: multiplexed inputs
|
||||
// if input mux(port H) is 0, port A status buffer & gate is selected (via Q5 NAND)
|
||||
if (offset == NEC_UCOM4_PORTA && m_inp_mux == 0)
|
||||
if (offset == 0 && m_inp_mux == 0)
|
||||
{
|
||||
// todo..
|
||||
return m_inputs[4]->read();
|
||||
data = m_inputs[4]->read();
|
||||
}
|
||||
else
|
||||
return read_inputs(4) >> (offset*4) & 0xf;
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (BIT(m_inp_mux, i))
|
||||
data |= m_inputs[i]->read();
|
||||
|
||||
data >>= (offset*4) & 0xf;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -234,36 +287,19 @@ INPUT_PORTS_END
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void tb303_state::machine_start()
|
||||
{
|
||||
hh_ucom4_state::machine_start();
|
||||
|
||||
// zerofill
|
||||
memset(m_ram, 0, sizeof(m_ram));
|
||||
m_ram_address = 0;
|
||||
m_ram_ce = false;
|
||||
m_ram_we = false;
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_ram));
|
||||
save_item(NAME(m_ram_address));
|
||||
save_item(NAME(m_ram_ce));
|
||||
save_item(NAME(m_ram_we));
|
||||
}
|
||||
|
||||
void tb303_state::tb303(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
NEC_D650(config, m_maincpu, TP2_HZ);
|
||||
m_maincpu->read_a().set(FUNC(tb303_state::input_r));
|
||||
m_maincpu->read_b().set(FUNC(tb303_state::input_r));
|
||||
m_maincpu->read_c().set(FUNC(tb303_state::ram_r));
|
||||
m_maincpu->write_c().set(FUNC(tb303_state::ram_w));
|
||||
m_maincpu->write_d().set(FUNC(tb303_state::ram_w));
|
||||
m_maincpu->write_e().set(FUNC(tb303_state::ram_w));
|
||||
m_maincpu->write_f().set(FUNC(tb303_state::ram_w));
|
||||
m_maincpu->write_g().set(FUNC(tb303_state::switch_w));
|
||||
m_maincpu->write_h().set(FUNC(tb303_state::switch_w));
|
||||
m_maincpu->read_c().set(FUNC(tb303_state::ram_data_r));
|
||||
m_maincpu->write_c().set(FUNC(tb303_state::ram_data_w));
|
||||
m_maincpu->write_d().set(FUNC(tb303_state::ram_address_w<0>));
|
||||
m_maincpu->write_e().set(FUNC(tb303_state::ram_address_w<2>));
|
||||
m_maincpu->write_f().set(FUNC(tb303_state::ram_address_w<1>));
|
||||
m_maincpu->write_g().set(FUNC(tb303_state::led_w));
|
||||
m_maincpu->write_h().set(FUNC(tb303_state::input_w));
|
||||
m_maincpu->write_i().set(FUNC(tb303_state::strobe_w));
|
||||
|
||||
timer_device &tp3_clock(TIMER(config, "tp3_clock"));
|
||||
|
@ -2,8 +2,6 @@
|
||||
// copyright-holders:hap
|
||||
/***************************************************************************
|
||||
|
||||
** subclass of hh_ucom4_state (includes/hh_ucom4.h, drivers/hh_ucom4.cpp) **
|
||||
|
||||
Roland TR-606 Drumatix, early 1982
|
||||
* NEC uCOM-43 MCU, labeled D650C 128
|
||||
* 2*uPD444C 1024x4 Static CMOS SRAM
|
||||
@ -15,29 +13,39 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/hh_ucom4.h"
|
||||
|
||||
#include "cpu/ucom4/ucom4.h"
|
||||
#include "machine/timer.h"
|
||||
|
||||
#include "tr606.lh"
|
||||
|
||||
|
||||
class tr606_state : public hh_ucom4_state
|
||||
class tr606_state : public driver_device
|
||||
{
|
||||
public:
|
||||
tr606_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
hh_ucom4_state(mconfig, type, tag)
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu")
|
||||
{ }
|
||||
|
||||
void tr606(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
|
||||
private:
|
||||
required_device<ucom4_cpu_device> m_maincpu;
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(tp3_clock) { m_maincpu->set_input_line(0, ASSERT_LINE); }
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(tp3_clear) { m_maincpu->set_input_line(0, CLEAR_LINE); }
|
||||
|
||||
virtual void machine_start() override;
|
||||
};
|
||||
|
||||
void tr606_state::machine_start()
|
||||
{
|
||||
// zerofill
|
||||
|
||||
// register for savestates
|
||||
}
|
||||
|
||||
// TP2 to MCU CLK: LC circuit(TI S74230), stable sine wave, 2.2us interval
|
||||
#define TP2_HZ 454545
|
||||
|
||||
@ -73,15 +81,6 @@ INPUT_PORTS_END
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
void tr606_state::machine_start()
|
||||
{
|
||||
hh_ucom4_state::machine_start();
|
||||
|
||||
// zerofill
|
||||
|
||||
// register for savestates
|
||||
}
|
||||
|
||||
void tr606_state::tr606(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
|
@ -1,53 +0,0 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:hap
|
||||
/*
|
||||
|
||||
NEC uCOM4 MCU tabletops/handhelds or other simple devices.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MAME_INCLUDES_HH_UCOM4_H
|
||||
#define MAME_INCLUDES_HH_UCOM4_H
|
||||
|
||||
#include "cpu/ucom4/ucom4.h"
|
||||
#include "video/pwm.h"
|
||||
#include "sound/spkrdev.h"
|
||||
|
||||
|
||||
class hh_ucom4_state : public driver_device
|
||||
{
|
||||
public:
|
||||
hh_ucom4_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_display(*this, "display"),
|
||||
m_speaker(*this, "speaker"),
|
||||
m_inputs(*this, "IN.%u", 0)
|
||||
{ }
|
||||
|
||||
// devices
|
||||
required_device<ucom4_cpu_device> m_maincpu;
|
||||
optional_device<pwm_display_device> m_display;
|
||||
optional_device<speaker_sound_device> m_speaker;
|
||||
optional_ioport_array<6> m_inputs; // max 6
|
||||
|
||||
// misc common
|
||||
u8 m_port[9]; // MCU port A-I write data (optional)
|
||||
u8 m_int; // MCU INT pin state
|
||||
u16 m_inp_mux; // multiplexed inputs mask
|
||||
|
||||
u32 m_grid; // VFD current row data
|
||||
u32 m_plate; // VFD current column data
|
||||
|
||||
u8 read_inputs(int columns);
|
||||
void refresh_interrupts(void);
|
||||
void set_interrupt(int state);
|
||||
DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
};
|
||||
|
||||
|
||||
#endif // MAME_INCLUDES_HH_UCOM4_H
|
Loading…
Reference in New Issue
Block a user